What's that exception you have here?

Mike Harder found this one that I didn't know about: all exceptions that you may get from the browser are not Error instances. DOMException is an exception that gets thrown when a DOM operation fails, but for some incomprehensible reason it doesn't derive from Error like SyntaxError or TypeError:

try{
    document.createElement(' ');
}
catch (ex){
    alert(ex instanceof Error);
}

This will alert false.

But wait, that's not all. There are other exceptions that derive from DOMException, so in order to handle that exception, you'd want to be able to know if an exception derives from it, something like that:

try{
    document.createElement(' ');
}
catch (ex){
    if (ex instanceof DOMException){
        // Do stuff
    }
}

Well, if you try that on Opera, you'll get a TypeError stating "DOMException does not implement [[HasInstance]]". Isn't that just awesome?

8 Comments

  • How common is it for script code to do different things based on the type of the exception anyway?

  • @Nikhil: most people don't bother but that's a bad thing: why would catch(Exception e) be bad practice in .NET and Java but not in script?

  • Yes, but in .NET it's considered a best practice to not depend on exceptions as the condition to perform a subsequent action. Most actions performed on an exception in .NET are for logging, something that's not very helpful to a user.

  • @Suman: what's your point? Are you saying that it's not useful to handle exceptions??

  • Not saying I agree, but perhaps the two different hierarchies are because some are JavaScript programming language related exceptions, while others are W3C DOM. That DOM was specified independent of implementation (ECMAScript), so perhaps it had its own inheritance hierarchy etc.

  • It certainly is unusual that DOMExceptions are not instances of Errors. But, it shouldn't really hinder your ability to do error handling all that much. I see that Opera doesn't support checking the instanceof a DOMException, but what about typeof?

    I'm curious, how much error handling do you put in your code? Like, how granular do you make it?

    I'm also interested in how different JavaScript libraries will either raise exceptions or swallow them. Like, Prototype will sometimes silently fail when defining a class, whereas MooTools seems to always raise exceptions. What's the rationale for this? It seems that you'd want to raise exceptions during development mode and silently catch and log the error via Ajax (but not raise the exception) in production. Thoughts?

  • Actually I personally believe there are several cases where catch (Exception e) is the right thing even in .NET. I think the design guidelines are a bit extreme (I might be in the minority camp on this one)

    Sometimes there are cases where code switches based on exception type, and its abusing the exception mechanism to implement control flow.

    Its not black and white. There are certainly valid cases though to catch a particular exception type. In .NET there are many more app scenarios - eg. you want to distinguish file not found from something else. Script simply doesn't have that many scenarios right now, to make it interesting to distinguish at the exception type level.

    In several cases, you want to figure out whats the right alternative a piece of code should do if a dependency threw an exception, and either do something alternative, or return a success/failure result. And that requires an unqualified catch block. If all code catches only specific exception types, then its likely that various exceptions will bubble to the root, where the global catch handler can only either end the app, report there was an error and resume... but it doesn't have much context to do some alternative behavior, or provide a better error report of the specific action that failed.

  • @Jonah: typeof can't help you here. typeof can only return the following strings: "string", "number", "boolean", "object", "function" or "undefined".
    I personally think swallowing exceptions is totally wrong in most cases. As you point out, one thing you might want to do is have your own global exception handler that doesn't expose the exceptions to the user but logs them or sends them back to the back-end. But of course that's very different from swallowing the exception, which makes it totally impossible to ever detect and correct problems.

    @Nikhil: I disagree that the exception system in script would justify catching specific expetions less than in .NET. If you think about it, the number of exception that you commonly use in .NET is also relatively small, but still you don't want to catch an out of memory exception where you really expect a null ref for example. In script, there are few kinds of exceptions (about a dozen) but they are all pretty common. Plus, frameworks such as Microsoft Ajax expose and use a rich system of exceptions.
    One place where it makes a lot of sense to catch specific exceptions is a unit testing system.

Comments have been disabled for this content.