I'm confused how to properly catch JavaScript exceptions. I have a background as a Java Dev, so much of what I know about error handling comes from it.
I'm using sequelize for persistence, so messing around with it, I found an example on the web:
try {
//do sequelize stuff
} catch (error){
switch (error.name) {
case 'SequelizeUniqueConstraintError':
//do something
break;
case 'SequelizeValidationError':
//do something else
break;
default:
//do panic stuff
}
}
Well... that encouraged me to take a look inside sequelizer's source code...
What is thrown, is basically that:
class UniqueConstraintError extends ValidationError {
constructor(options) {
options = options || {};
options.parent = options.parent || { sql: '' };
options.message = options.message || options.parent.message || 'Validation Error';
options.errors = options.errors || {};
super(options.message, options.errors);
this.name = 'SequelizeUniqueConstraintError';
this.errors = options.errors;
this.fields = options.fields;
this.parent = options.parent;
this.original = options.parent;
this.sql = options.parent.sql;
}
}
hmmm... Interesting.... why would an exception have a name, besides already having a type? So I changed my code to deal with the types themselves instead of the names, and it ended up like this:
try {
//do sequelize stuff
} catch (error){
if (error instanceof UniqueConstraintError) {
//do something
} else if (error instanceof ValidationError) {
//do something else
} else {
//do panic stuff
}
}
Needless to say, both work just fine.
Is there something I'm missing here? Am I following the wrong tutorials?
Witch solution would be the 'par excellence' in order to deal with multiple possible exceptions being thrown in modern JavaScript?? (witch may be not necessarily any of the two I've presented here)
Thanks.
CodePudding user response:
Why would an exception have a name, besides already having a type?
For the same reason as using error codes: they serialise well and don't require a reference to the class. Also in some rare occasions (that should be avoided) you might end up with multiple copies of the library being loaded, which define multiple distinct classes with the same name. Checking the .name
string still works, using instanceof
only works if you reference the same class.
Which solution would be the 'par excellence' in order to deal with multiple possible exceptions being thrown in modern JavaScript?
If instanceof
works for you, there's nothing wrong with using it - it's perfectly idiomatic. It's just that some programmers prefer a more defensive style that's more resilient in the face of bugs. Using string constants has its own set of problems, e.g. being prone to misspelling and API incompatibility.
CodePudding user response:
Checking the value of a name
property may be considered safer and/or simpler because:
for example, an instance of
UniqueConstraintError
is also an instance ofValidationError
because the former extends the latter, so the order of theinstanceof
checks is crucial, and easy to get wrong.for example,
instanceof UniqueConstraintError
may returnfalse
if the instance originated from a different execution context with its own global scope, such as that of aniframe
.
If you are happy that neither of these reasons is pertinent then instanceof
is more idiomatic and the better choice in my opinion.