Ending the JavaScript Error Epidemic
I don't know about you, but I'm absolutely tired of getting JavaScript errors on 50% of the websites I visit. It's pretty much become an expectation that if you visit certain sites (http://www.weather.com comes to mind) you're going to get a JavaScript error. Why? Is it because no one cares, or because no one notices? Either way it's out of control, and it seems that everyone has simply accepted this behavior of the WWW at this point. Being a web developer my browser is always set to show me JavaScript errors and prompt me to debug. I do this so that I'm made aware when I introduce a JavaScript error into one of my pages, however it also makes me aware when anyone else does too. I think it's time that we force a change, and hopefully together we can catalyze this change - turning unhandled JavaScript errors into the exception not the rule.
Do I think that tomorrow everyone will be writing bug free JavaScript ? Not a chance. However, I see no reason why web developers can't start being more responsible for their code (bugs). A couple of months ago I started thinking about global error handling and came up with a prototype. My original prototype worked by including a JavaScript file in your application, and importing into your page. The script was pretty straight forward - it added an onerrror event handler to the page in order to capture any unhandled exceptions. It worked great, and kept errors from bubbling up to the end user. I view this as the minimum step all web developers should be taking - capturing unhandled events in a deployed application to prevent end users from seeing the error details. Here's an example of how to trap unhandled exceptions.
function handleErrors(errStr, url, lineNum){ ... }
window.onerror=handleErrors;
I said that the above was a minimum because there's more that you can do.. a lot more. Once you have successfully trapped an error, there's a great deal of information available to help diagnose or debug the problem. You can even construct a stack trace of your JavaScript functions by using the .caller property of a function prototype. Here's an example:
function getStackTrace(func){
if(!func)return "";
var trace=getFuncName(func);
var args="(";
for(var arg in func.arguments){
if(args&&args.length&&args.length>1)args+=",";
args+=func.arguments.toString();
}
trace+=args+")\n";
return trace+getStackTrace(func.caller);
}
At this point we've prevented an error from being surfaced up to the UI and hence prevented a user from being annoyed, and we've also obtained some information about the error by constructing a stacktrace as shown above. So where do we go from here? Reporting the error back to the server would be the next step. There are a couple of different ways you can do this - you can use an HTTP Get using a REST like approach, or you can post the values back to the server and further process the information. Using an XMLHTTP request, the data can be posted back to the server asynchronously with out interrupting the end user. I personally like the second technique, because it offers you a high level of flexibility, though it is a bit more work.
I've decided to take this up as a side project, and create an error handling and reporting mechanism for anyone to use. I'm not quite ready to publish the code at this point, but I'm hoping to have something ready in the next few weeks.