What are the best practices for JavaScript error handling?
I'm looking to start making my JavaScript a bit more error proof, and I'm finding plenty of documentation on using try
, catch
, finally
, and throw
, but I'm not finding a ton of advice from experts on when and where to throw errors.
- Should every piece of code be wrapped in a try/catch?
- Is there more advice like this on at what point errors ought to be caught?
- Are there disadvantages to raising errors instead of having code fail silently in production?
- This has been touched on on SO as far as implementations, but have server-logging JS errors an effective strategy?
- Anything else I ought to know, regarding trapping errors in my application?
I'm also completely game for hearing of books that have great chapters or in-depth explanations of error-handling. Eloquent JavaScript touches on the matter, but isn't very prescriptive or opinionated about the issue.
Thanks for any advice you can give!
Solution 1:
An immensely interesting set of slides on Enterprise JavaScript Error Handling can be found at https://web.archive.org/web/20140126104824/http://www.devhands.com/2008/10/javascript-error-handling-and-general-best-practices/
In short it summarizes:
- Assume your code will fail
- Log errors to the server
- You, not the browser, handle errors
- Identify where errors might occur
- Throw your own errors
- Distinguish fatal versus non-fatal errors
- Provide a debug mode
The slides go into much more detail and most probably will give you some direction.
EDIT:
The presentation mentioned above can be found here: https://www.slideshare.net/nzakas/enterprise-javascript-error-handling-presentation
Solution 2:
Nicholas Zakas of Yahoo! fame did a talk on Enterprise Error Handling (slides) at Ajax Experience 2008, in which he proposed something like this:
function log(sev,msg) {
var img = new Image();
img.src = "log.php?sev=" +
encodeURIComponent(sev) +
"&msg=" + encodeURIComponent(msg);
}
// usage
log(1, "Something bad happened.")
// Auto-log uncaught JS errors
window.onerror = function(msg, url, line) {
log(1, msg);
return true;
}
A year later, Nicholas Zakas posted an update on his blog which included a clever pattern to inject error handling code automatically on your production environment (using aspect-oriented programming).
When you start logging window.error calls, you're going to notice two things:
- If your site is fairly complex, you're going to log a lot of errors
- You'll be seeing a bunch of useless "window.error in undefined:0" messages
Reducing the torrent of log entries is as simple as testing for severity and/or a random number before logging to the server:
function log(sev,msg) {
if (Math.random() > 0.1) return; // only log some errors
var img = new Image();
img.src = "log.php?sev=" +
encodeURIComponent(sev) +
"&msg=" + encodeURIComponent(msg);
}
Handling the useless window.error in undefined:0
errors depends on your site architecture, but can try identifying all Ajax calls and throwing an exception when something fails (possibly returning a stack trace using stacktrace.js).