node.js: Throwing error and it's not being caught-Collection of common programming errors
I have an API using swagger integrated with express on node.js and a resource defined as below. A swagger error thrown in the check for (!req.params.id), is caught by swagger’s default error handler. An error thrown in the callback from the mongoDB delete call is NOT caught, giving me the error below. The error looks like it has to do with the scope/order of the callback function, and as somebody new to node.js I was hoping to get advice on how to do this properly, maintaining asynchronicity. -thanks
events.js:74 throw TypeError(‘Uncaught, unspecified “error” event.’); ^ TypeError: Uncaught, unspecified “error” event.
exports.remove = {
'spec' : {
"collapsed...for...brevity..." : "...",
"params" : [ {
"paramType" : "path",
"name" : "id",
"collapsed...for...brevity..." : "...",
}],
"errorResponses" : [ swe.notFound('id'), swe.invalid('id') ],
"nickname" : "remove"
},
'action' : function(req, res) {
if (!req.params.id) {
throw swe.invalid('id'); // THIS ERROR IS CAUGHT
}
req.coll.remove({_id : req.coll.id(req.params.id)}, function(e, result) {
if (e) {
throw swe.invalid('collection'); // THIS ERROR IS NOT CAUGHT
}
res.send({msg : 'success'});
});
}
};
-
Rule 1. Don’t throw in callback. Better don’t throw at all. Throw only if you want the process to crash. If you need to pass error to the caller use
callback(err)
. If you are in connect/express middleware scope you can also usenext(err)
.Rule 2. If something is still thrown and you want to catch it, use domains. Considering rule 1 this way you can catch only super-unexpected things, so you HAVE TO take down the process as soon as possible.
-
Exceptions thrown within an async callback go to the caller of the callback, not your surrounding code. So it’s the
req.coll.remove
code that receives the exception (which isn’t handling it) and that crashes your app.Instead, you need to have your remove
action
function accept a callback parameter that it can use to communicate errors back to the caller.This is why exceptions are rarely used in node.js code and callbacks are the standard.