24

Douglas Crockford recommends doing something like this:

throw {
    name: "System Error",
    message: "Something horrible happened."
};

But you could also do something like this:

function IllegalArgumentException(message) {
    this.message = message;
}

throw new IllegalArgumentException("Argument cannot be less than zero");

and then do:

try {
    //some code that generates exceptions
} catch(e) {    
    if(e instanceof IllegalArgumentException) {
        //handle this
    } else if(e instanceof SomeOtherTypeOfException) {
        //handle this
    }
}

I guess you could include a type property in Crockford's implementation and then examine that instead of doing an instanceof. Is there any advantage from doing one versus the other?

Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
  • 3
    For someone used to Java-style exceptions, the second form looks much... more familiar. – NullUserException Oct 25 '12 at 21:39
  • 1
    Yes, I'm partial to the second for that very reason. :) – Vivin Paliath Oct 25 '12 at 21:40
  • 4
    I am in favor of the second one since it is more reusable in terms of code purity. To be precise, if I am about to throw the same exception type on several places, my code would get messy (immense) with the first approach. – zpavlinovic Oct 25 '12 at 21:43
  • @bellpeace Good point. I like the encapsulation advantage that it offers. Indeed, I am throwing exceptions in several places and the first approach is starting to get unwieldy. If you post it as an answer, I can accept it. – Vivin Paliath Oct 25 '12 at 21:45
  • Does this answer your question? [What's a good way to extend Error in JavaScript?](https://stackoverflow.com/questions/1382107/whats-a-good-way-to-extend-error-in-javascript) – rene Nov 10 '22 at 10:30

2 Answers2

27

Update 2022

If your environment supports ES6, you should use inheritance from Error class, as recommended by Mozilla:

class IllegalArgumentException extends Error {
   // ...
}

This is also the most upvoted answer in What's a good way to extend Error in JavaScript?.


Pre-ES6 (original answer)

Also pre-ES6 environments provide the Error class as basis for exceptions. It already allows you to define a message, but also provides a useful stack property to track down the context of the exception. You can create your own exception type by using prototypical inheritance. There are already several stackoverflow discussions (for example: here), how to do this properly. However, I had to dig a little bit until I found the correct and modern approach. Please be aware that the approach that is suggested in the Mozilla documentation (see above) is not liked by the stackoverflow community. After a lot of reading I came out with that approach for inherit from Error.prototype:

function IllegalArgumentException(sMessage) {
    this.name = "IllegalArgumentException";
    this.message = sMessage;
    this.stack = (new Error()).stack;
}
IllegalArgumentException.prototype = Object.create(Error.prototype);
IllegalArgumentException.prototype.constructor = IllegalArgumentException;
rene
  • 1,618
  • 21
  • 26
4

I am in favor of the second one since it is more reusable in terms of code purity. To be precise, if I am about to throw the same exception (even the same exception type with a different message) on several places, my code would get messy (immense) with the first approach.

zpavlinovic
  • 1,507
  • 1
  • 17
  • 36