Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch express bodyParser error

I want to catch the error from the bodyParser() middleware when I send a json object and it is invalid because I want to send a custom response instead of a generic 400 error.

This is what I have and it works:

app.use (express.bodyParser ());
app.use (function (error, req, res, next){
    //Catch bodyParser error
    if (error.message === "invalid json"){
        sendError (res, myCustomErrorMessage);
    }else{
        next ();
    }
});

But this seems to me a very ugly approach because I'm comparing the error message which could change in future express versions. There's any other way to catch bodyParser() errors?

EDIT:

This is the error when the request body has an invalid json:

{
  stack: 'Error: invalid json\n    at Object.exports.error (<path>/node_modules/express/node_modules/connect/lib/utils.js:55:13)\n    at IncomingMessage.<anonymous> (<path>/node_modules/express/node_modules/connect/lib/middleware/json.js:74:71)\n    at IncomingMessage.EventEmitter.emit (events.js:92:17)\n    at _stream_readable.js:872:14\n    at process._tickDomainCallback (node.js:459:13)',
  arguments: undefined,
  type: undefined,
  message: 'invalid json',
  status: 400
}

Pretty printed stack:

Error: invalid json
    at Object.exports.error (<path>/node_modules/express/node_modules/connect/lib/utils.js:55:13)
    at IncomingMessage.<anonymous> (<path>/node_modules/express/node_modules/connect/lib/middleware/json.js:74:71)
    at IncomingMessage.EventEmitter.emit (events.js:92:17)
    at _stream_readable.js:872:14
    at process._tickDomainCallback (node.js:459:13)
like image 326
Gabriel Llamas Avatar asked Apr 04 '13 18:04

Gabriel Llamas


People also ask

What does bodyParser do in Express?

Express body-parser is an npm library used to process data sent through an HTTP request body. It exposes four express middlewares for parsing text, JSON, url-encoded and raw data set through an HTTP request body. These middlewares are functions that process incoming requests before they reach the target controller.

Is bodyParser deprecated 2021?

body parser package is deprecated. If you are using latest version of express you don't have to install body-parser package.

Do I need to use bodyParser in Express?

bodyParser was added back to Express in release 4.16. 0, because people wanted it bundled with Express like before. That means you don't have to use bodyParser.

Is bodyParser deprecated?

'bodyParser' is deprecated. // If you are using Express 4.16+ you don't have to import body-parser anymore.


6 Answers

I think your best bet is to check for SyntaxError:

app.use(function (error, req, res, next) {
  if (error instanceof SyntaxError) {
    sendError(res, myCustomErrorMessage);
  } else {
    next();
  }
});
like image 71
robertklep Avatar answered Oct 08 '22 05:10

robertklep


From the answer of @alexander but with an example of usage

app.use((req, res, next) => {
    bodyParser.json({
        verify: addRawBody,
    })(req, res, (err) => {
        if (err) {
            console.log(err);
            res.sendStatus(400);
            return;
        }
        next();
    });
});

function addRawBody(req, res, buf, encoding) {
    req.rawBody = buf.toString();
}
like image 31
Daniel Pérez Avatar answered Oct 08 '22 07:10

Daniel Pérez


Ok, found it:

bodyParser() is a convenience function for json(), urlencoded() and multipart(). I just need to call to json(), catch the error and call to urlencoded() and multipart().

bodyParser source

app.use (express.json ());
app.use (function (error, req, res, next){
    //Catch json error
    sendError (res, myCustomErrorMessage);
});

app.use (express.urlencoded ());
app.use (express.multipart ());
like image 39
Gabriel Llamas Avatar answered Oct 08 '22 05:10

Gabriel Llamas


what I did was just:

app.use(bodyParser.json({ limit: '10mb' }))
// body parser error catcher
app.use((err, req, res, next) => {
  if (err) {
    res.status(400).send('error parsing data')
  } else {
    next()
  }
})
like image 39
Erick Garcia Avatar answered Oct 08 '22 06:10

Erick Garcia


All errors include a type property from 1.18.0 release onwards. For parse failure, err.type === 'entity.parse.failed'.

app.use(function (error, req, res, next) {
if (error.type === 'entity.parse.failed') {
 sendError(res, myCustomErrorMessage);
} else {
 next();
}
});
like image 36
sunmonu oluwole Avatar answered Oct 08 '22 05:10

sunmonu oluwole


I found checking for SyntaxError to be not enough, therefore I do:

if (err instanceof SyntaxError &&
  err.status >= 400 && err.status < 500 &&
  err.message.indexOf('JSON') !== -1) {
    // process filtered exception here
}
like image 33
dudko Avatar answered Oct 08 '22 06:10

dudko