I'm building an API (using Expressjs v4) and typically I've dealt with errors within the route rather than using middleware. For example:
router.use('/', function(req, res, next) {
...
if (err)
return res.status(500).send({type: "serverError", message: "Something has gone wrong on our end."});
}
I now realise that middleware is the "way to go." I've seen the rather limited documentation on the Expressjs site here: http://expressjs.com/guide/error-handling.html but still unsure of a few things.
I've added in the server.js
:
function errorHandler(err, req, res, next) {
}
but how do I supposed to handle the different types of errors (400,404,500 etc)?
I'm finding myself writing 3 lines of code each time an error occurs:
//A route
var err = new Error();
err.status = 404;
return next(err);
and I can access the status using:
function errorHandler(err, req, res, next) {
console.log(err.status);
if(err.status == "400")
//do something
else
//etc etc
}
Surely there's an easier way than this? Am I missing something?
Express comes with a default error handler for handling error conditions. This is a default middleware function added by Express at the end of the middleware stack. We call the error handling middleware by passing the error object to the next(error) function.
Middleware functions are an integral part of an application built with the Express framework (henceforth referred to as Express application). They access the HTTP request and response objects and can either terminate the HTTP request or forward it for further processing to another middleware function.
Note: Router functions are Express middleware, which means that they must either complete (respond to) the request or call the next function in the chain.
Instead manually creating error, you can delegate that error like below.
return next(err);
And your error will go deep down all the routes defined until it find routes with below signature.
app.use(function (err, req, res, next) {
});
You can see the err argument in above route.
Ideally you can use below two methods for both DEVELOPMENT & PRODUCTION environment.
if (process.env.NODE_ENV === 'development') {
app.use(function (err, req, res, next) {
res.status(err.status || 500);
logger.log('info', err.message + " expected URL was " + req.url);
res.status(err.status).send(err.status, {
message: err.message,
error : err
});
});
}
app.use(function (err, req, res, next) {
res.status(err.status || 500);
logger.log('error', err.message + " expected URL was " + req.url);
res.status(err.status).send(err.status, {
message: err.message,
error : {}
});
});
You can capture actual populated error object in there.
You should create your own Error type that allows you to provide all the information necessary to act on the error.
var util = require('util');
function HttpError(message, statusCode){
this.message = message;
this.statusCode = statusCode;
this.stack = (new Error()).stack;
}
util.inherits(Error, HttpError);
module.exports = HttpError;
Then include your new error object in your code and use it like
next(new HttpError('Not Found', 404));
Or you could go crazy and implement an error type for each response code pre-populating the statusCode
part.
Ref: What's a good way to extend Error in JavaScript?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With