I'm using the body-parser
package like this:
// For parsing application/json:
app.use(require('body-parser').json());
// For parsing application/x-www-form-urlencoded
app.use(require('body-parser').urlencoded({ extended: true }));
When a valid input like { "foo": "bar" }
is received everything works fine and I can access the parsed object with req.body
.
However, when invalid (non-JSON) data is sent:
data: JSON.stringify("just something inappropriate"),
I get this error:
{ SyntaxError: Unexpected token " in JSON at position 0
at JSON.parse (<anonymous>)
at createStrictSyntaxError
at ...
expose: true,
statusCode: 400,
status: 400,
body: '"Something"',
type: 'entity.parse.failed' }
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client at ...
How can I handle this properly to prevent the server from shutting down?
One option is to add a custom error handler middleware and add a check to catch JSON parsing errors like that one:
app.use(require('body-parser').json());
app.use(require('body-parser').urlencoded({ extended: true }));
...
app.use((err, req, res, next) => {
// This check makes sure this is a JSON parsing issue, but it might be
// coming from any middleware, not just body-parser:
if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
console.error(err);
return res.sendStatus(400); // Bad request
}
next();
});
Another option is to wrap body-parser
's middleware to catch errors coming only from there:
const bodyParser = require('body-parser');
app.use((req, res, next) => {
bodyParser.json()(req, res, err => {
if (err) {
console.error(err);
return res.sendStatus(400); // Bad request
}
next();
});
});
Or if you want to reuse this functionality to catch different errors from different middlewares, you can do:
function handleError(middleware, errorHandler) {
middleware(req, res, err => err ? errorHandler(err, req, res, next) : next());
}
const bodyParser = require('body-parser');
app.use(handleError(bodyParser.json(), (err, req, res, next) => {
if (err) {
console.error(err);
return res.sendStatus(400); // Bad request
}
next();
}));
As of Express 4.16.0 - Release date: 2017-09-28 you can catch different errors from different middlewares splitting the error handler into a different function without using Bodyparser as it is deprecated.
const app = express();
function handleError(middleware, req, res, next) {
middleware(req, res, (err) => {
if (err) {
console.error(err);
return res.sendStatus(400); // Bad request
}
next();
});
}
app.use((req, res, next) => {
handleError(express.json(), req, res, next);
});
Notice in the code as of Express 4.16.0 and higher that express:
app.use(express.json()); // Without middleware error handling.
replaces bodyParser:
app.use(bodyParser.json()); // Without middleware error handling.
Add an error handler and then customize the behavior of the default way to handle that erorr, the default will be to crash as you describe.
app.use((err, req, res, callback) => {
// todo: implement error handling logic and return an appropriate response
console.error(err)
res.send(500)
callback()
})
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