I need a script that can determine the reason an image didn't load based on the HTTP status code supplied.
I am aware of the onError event on images and objects, but it does not pass the error code. So if an image has a broken source or a time out occurred are dealt with the same way.
What I would like is to have a script that can determine the error code and act accordingly.
For example:
404 - replace image with a predefined one
403 - notify admin using an callback function
504 - try to reload
etc.
I've done some searching on google, but other than the onError event I came up short.
Any ideas?
the only thing i can think of is to go to a xhr request on fail, with Asset.image from more handling the loading:
new Asset.image('foo.jpg', {
onload: function() {
someel.adopt(this);
},
onerror: function() {
new Request({
url: this.get('src'),
onComplete: function() {
console.log(this.status); // 404
}
}).get();
}
});
http://jsfiddle.net/dimitar/2hwej/
not exactly the greatest as it would mean 2 requests. to go around that, you can put your image loading into a xhr request to begin with and then use base64 data to output or something.
Related
I'm using $("#element").attr("src", "http://url.com/page"); to set several iframes.
Is there a way to determine if an HTTP error occurred while setting a specific iframe and handle it accordingly?
The onerror event of the <iframe> does not work anymore, unfortunately.
Still, you could use a workaround like this :
Bind a load event to all of the iframes you are loading
Throw a setTimeout with arbitrary time for each <iframe>, like 60000 (1mn) or less in the mean time
If the load event triggers, clear the setTimeout.
It's not complete error handling, more a workaround. I used to do it with JSONP requests as there is no error handling too.
var timeout;
$("#iframe").attr("src", "url-cross-domain.html").on("load", function() {
clearTimeout(timeout);
console.log("loaded !");
}):
timeout = setTimeout(function() {
$("#iframe").off("load").remove();
console.error("iframe loading failed");
}, 60000);
It has several limitations, for example you'll be unable to get the request response code. But it worth a try.
I wrote simple code to check is image loaded
imageLoadErrorCheck: function() {
$('img').on('error', function() {
$(this).addClass('img_errorShowInfo');
$(this).prop('src', '/assets/default/img/404.png');
});
},
but somehow in some cases this code is not working approx in 1 on 20 refreshes it's not triggering (I'm checking now in Chrome only).
Is any better way to recognize when an image was not loaded?
E.g. console always throwing GET 404 error, maybe is a way to catch this?
Today I find the need to track and retrieve a Javascript error stacktrace to solve them.
Today we were able to capture all rest calls, the idea is that once you get an error, automatically posts the stacktrace of that error plus the responses of the rest saved services so we can detect, reproduce, and solve the problems in almost an identical environment/situation.
As a requirement we were asked to make a module that can be included without being intrusive, for example:
Include the module that contains the hook logic in one JS, would be not invasive, include several lines of code in various JS files would be invasive.
The goal is to make a tool that can be included in a system already developed and track error events (like console).
I've read about this trackers logic:
errorception.com/
trackjs.com/
atatus.com/
airbrake.io/
jslogger.com/
getsentry.com/
muscula.com/
debuggify.net/
raygun.io/home
We need to do something like that, track the error and send it to our server.
As "Dagg Nabbit" says... "It's difficult to get a stack trace from errors that happen "in the wild" right now"...
So, we got a lot of paid products, but how did they really works?
In Airbrake they use stacktrace and window.onerror:
window.onerror = function(message, file, line) {
setTimeout(function() {
Hoptoad.notify({
message : message,
stack : '()#' + file + ':' + line
});
}, 100);
return true;
};
But i cant figure out when the stacktrace really used.
At some point, stacktrace, raven.js and other trackers need try / catch.
what happens if we found a way to make a global wrapper?
Can we just call stacktrace and wait for the catch?
How can I send a stack trace to my server when an unexpected error occurs on the client? Any advice or good practices?
It's difficult to get a stack trace from errors that happen "in the wild" right now, because the Error object isn't available to window.onerror.
window.onerror = function(message, file, line) { }
There is also a new error event, but this event doesn't expose the Error object (yet).
window.addEventListener('error', function(errorEvent) { })
Soon, window.onerror will get a fifth parameter containing the Error object, and you can probably use stacktrace.js to grab a stack trace during window.onerror.
<script src="stacktrace.js"></script>
<script>
window.onerror = function(message, file, line, column, error) {
try {
var trace = printStackTrace({e: error}).join('\n');
var url = 'http://yourserver.com/?jserror=' + encodeURIComponent(trace);
var p = new printStackTrace.implementation();
var xhr = p.createXMLHTTPObject();
xhr.open('GET', url, true);
xhr.send(null);
} catch (e) { }
}
</script>
At some point the Error API will probably be standardized, but for now, each implementation is different, so it's probably smart to use something like stacktracejs to grab the stack trace, since doing so requires a separate code path for each browser.
I'm the cofounder of TrackJS, mentioned above. You are correct, sometimes getting the stack traces requires a little bit of work. At some level, async functions have to be wrapped in a try/catch block--but we do this automatically!
In TrackJS 2.0+, any function you pass into a callback (addEventListener, setTimeout, etc) will be automatically wrapped in a try/catch. We've found that we can catch nearly everything with this.
For the few things that we might now, you can always try/catch it yourself. We provide some helpful wrappers to help, for example:
function foo() {
// does stuff that might blow up
}
trackJs.watch(foo);
In latest browsers, there is a 5th parameter for error object in window.onerror.
In addEventListener, you can get error object by event.error
// Only Chrome & Opera pass the error object.
window.onerror = function (message, file, line, col, error) {
console.log(message, "from", error.stack);
// You can send data to your server
// sendData(data);
};
// Only Chrome & Opera have an error attribute on the event.
window.addEventListener("error", function (event) {
console.log(e.error.message, "from", event.error.stack);
// You can send data to your server
// sendData(data);
})
You can send data using image tag as follows
function sendData(data) {
var img = newImage(),
src = http://yourserver.com/jserror + '&data=' + encodeURIComponent(JSON.stringify(data));
img.crossOrigin = 'anonymous';
img.onload = function success() {
console.log('success', data);
};
img.onerror = img.onabort = function failure() {
console.error('failure', data);
};
img.src = src;
}
If you are looking for opensource, then you can checkout TraceKit. TraceKit squeezes out as much useful information as possible and normalizes it. You can register a subscriber for error reports:
TraceKit.report.subscribe(function yourLogger(errorReport) {
// sendData(data);
});
However you have to do backend to collect the data and front-end to visualize the data.
Disclaimer: I am a web developer at https://www.atatus.com/ where you can track all your JavaScript errors and filter errors across various dimensions such as browsers, users, urls, tags etc.
#Da3 You asked about appenlight and stacktraces. Yes it can gather full stacktraces as long as you wrap the exception in try/catch block. Otherwise it will try reading the info from window.onerror which is very limited. This is a browser limitation (which may be fixed in future).
I am looking to change the URL of a clip when the stream is not found. I am properly configuring the onError event, as I can debug the specific line or add an alert, but what I am having trouble with is the following:
onError : function(errorCode, errorMessage) {
this.getClip(0).update( { url : 'http://full-url.com/images/stream-not-found.png' } );
}
The problem is this image is never being loaded to the player upon the error -- I get a stream not found error message and then the player continues to look for this 'unfound' stream. I'm able to hit the URL and see the image, but am unable to change over upon stream not found. Per the documentation it is supposed to be able to take an image as the URL, but using a fully qualified or relative URL doesn't seem to be working.
This is somewhat simplified as we are looking to use customized images for each error code.
No real answer was determined for this, the best that could be done was to unload the player, and display the HTML which was in the container prior to the player being loaded.
At that point we still had an error number, so we were able to then use jQuery to set the html to display the new image.
Don't have code in front of me, but was similar to:
onError: function(errorCode, errorMessage) {
this.unload();
switch (errorCode) {
case 200:
$('#idOfPlayer a').attr('src', link-to-200-error.jpg);
break;
}
}
I do a bunch of json requests with dynamic script tags. Is it possible to detect if there's an error in the request (eg. 503 error, 404 error) and run something on detection of the error?
use ajax instead. AFAIK there is no way to detect if a script tag loads or not, and if not, why it didn't load. Using ajax you can load the json and it will tell you why it didn't load.
Using a library like jQuery this becomes very simple:
$.ajax({
type: "GET",
url: "test.js",
dataType: "script",
error: function(xhr, error, exception){
alert(xhr.status); //Will alert 404 if the script does not exist
}
});
AFAIK, there's no way to access status code of some external asset loaded from the document (such as script, style or image). Even detecting error (via, say, onerror event handler) is not that widely supported across browsers.
If whatever you're loading falls under SOP, use XHR which gives you access to response headers. Otherwise, you can try looking into recently introduced X-domain XHR.
I'm assuming you want this to work cross-domain, which is why you can't use XHR?
Try creating two script tags for each request, the first does your standard JSONP request, the second is basically an error handler.
If the first script tag executes, then clear the error handler in your callback. But if the first gets a 404, the error handler inside the second script tag will be run.
You probably also want to set a timeout, to cope with a slow JSONP response.
http://www.phpied.com/javascript-include-ready-onload/ ?
If you're using jQuery, check out jQuery-JSONP which is a jQuery plugin that does a fairly decent job of doing the <script> insertion for you as well as detecting fetch errors.
Quoting from the project page, jQuery-JSONP features:
error recovery in case of network failure or ill-formed JSON responses,
precise control over callback naming and how it is transmitted in the URL,
multiple requests with the same callback name running concurrently,
two caching mechanisms (browser-based and page based),
the possibility to manually abort the request just like any other AJAX request,
a timeout mechanism.
If you need to cross domains (and need the page to work portably), you have to use dynamic script tags.
If you have access to the remote server, you can pass back an error code from the server, and have the server page return 200.
Whether you have access or not, you can use setTimeout when you create the script tag, passing a function that will trigger an error if it expires before the jsonp handler is called. Make sure that the jsonp handler aborts if the error handler has been called.
You'll need to track each request through a global collection, but you'll gain the ability to cancel and count requests. This is similar to the way that XHR objects are managed by a library like jQuery.
If you want to detect errors, listen for an error event and compare the fileName property of the error with the file name of the script. If they match, you then handle the error. The thing is, I think that the fileName property is Firefox and Opera-only. Most browsers that have a stacktrace for errors can also simulate this behaviour.
Here's an example, as requested by Eric Bréchemier:
var getErrorScriptNode = (function () {
var getErrorSource = function (error) {
var loc, replacer = function (stack, matchedLoc) {
loc = matchedLoc;
};
if ("fileName" in error) {
loc = error.fileName;
} else if ("stacktrace" in error) { // Opera
error.stacktrace.replace(/Line \d+ of .+ script (.*)/gm, replacer);
} else if ("stack" in error) { // WebKit
error.stack.replace(/at (.*)/gm, replacer);
loc = loc.replace(/:\d+:\d+$/, "");
}
return loc;
},
anchor = document.createElement("a");
return function (error) {
anchor.href = getErrorSource(error);
var src = anchor.href,
scripts = document.getElementsByTagName("script");
anchor.removeAttribute("href");
for (var i = 0, l = scripts.length; i < l; i++) {
anchor.href = scripts.item(i).src;
if (anchor.href === src) {
anchor.removeAttribute("href");
return scripts.item(i);
}
}
};
}());