Reputation:
I have a function called a
that accepts a callback, which is invoked with an error if there is one.
a
is invoked in an Express route request. If there is an error, the error should be the response of the request.
function a(cb) {
cb(new Error('Some error message'))
}
app.get('/', function (req, res) {
a(function (error) {
if (error) {
res.json(error, 400)
}
res.send('No error')
})
})
I have looked into the code for Express, and it appears that res.json
will stringify my error
. However, the result of this is an empty string:
> var e = new Error('Some error message')
undefined
> JSON.stringify(e)
'{}'
> e.message
'Some error message'
There are ways I could get my route to return the error message here, such as converting the error object toString
in my route. However, I would like to know what the best practice is for formatting error messages in Node APIs, and whether that changes things here. Should I format my error messages differently, or should I just handle the Error
object in the route, such as:
res.json({ error: error.message }, 400)
Upvotes: 7
Views: 9264
Reputation: 2426
The right way to throw an error is to use an informative error instead of a generic error. Generic errors should only be thrown if the informative error itself fails for some reason. Here's a generic handler I use demonstrating custom errors and falling back to a generic error:
fpToExpressJson = async (response, next, fp, args) => {
const oResponse = await fp(args).catch(err => err);
if (!oResponse) {
return next(createError(404));
}
if (oResponse.errorCode) {
// Good job developer! You threw a descriptive error.
try {
return response.status(oResponse.errorCode).send(oResponse);
} catch (error) {
return next(error);
}
}
return response.json(oResponse);
};
Upvotes: 0
Reputation: 14953
To add to @steveukx's answer, you can specify an error handler in express, by .use
ing a function with arity of four.
app.use(function(err, req, res, next){
res.json(500, {
error: err.message
});
});
Which will be called whenever you do next(err)
.
See the docs.
Upvotes: 6
Reputation: 4368
Express routes can use a third argument next
that can be used to either skip the current route by just calling next()
, or to pass on errors by calling next(err)
.
Try using:
app.get('/', function (req, res, next) {
a(function (error) {
if (error) {
next(error);
}
else {
res.send('No error')
}
});
});
For more information, check out http://expressjs.com/api.html#app.param
Upvotes: 1
Reputation: 63179
I don't now what your response look like, when no error occurs, but this is how I usually handle JSON responses:
function (err, data) {
if (err) {
res.json({
success: false,
error: err.message
}, 400);
}
else {
res.json({
success: true,
data: data
});
}
}
Try to wrap this in a extra middleware/function. Keep the signature of the functions similar to standard node style. (First parameter error, following parameter the actual data.) This way it is much easy for the client to process you responses, because all you have to do is look into the success
field.
Upvotes: 1