Vivin Paliath
Vivin Paliath

Reputation: 95528

Throwing custom exceptions in Javascript. Which style to use?

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?

Upvotes: 24

Views: 8653

Answers (2)

rene
rene

Reputation: 1718

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;

Upvotes: 27

zpavlinovic
zpavlinovic

Reputation: 1547

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.

Upvotes: 4

Related Questions