Catch express bodyParser error

Javascriptnode.jsExpress

Javascript Problem Overview


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)

Javascript Solutions


Solution 1 - Javascript

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();
  }
});

Solution 2 - Javascript

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();
}

Solution 3 - Javascript

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 ());

Solution 4 - Javascript

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()
  }
})

Solution 5 - Javascript

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();
}
});

Solution 6 - Javascript

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
}

Solution 7 - Javascript

create new module "hook-body-parser.js" hook everything with body parser over here

const bodyParser = require("body-parser");

module.exports = () => {
  return [
    (req, res, next) => {
      bodyParser.json()(req, res, (error) => {
        if (error instanceof SyntaxError) {
          res.sendStatus(400);
        } else {
          next();
        }
      });
    },
    bodyParser.urlencoded({ extended: true }),
  ];
};

and use over express like this

... app.use(hookBodyParser()) ...

Solution 8 - Javascript

if you want to catch all errors thrown by body-parsr for example entity.too.large or encoding.unsupported

just place this middleware right after your body-parser initialization

$ npm i express-body-parser-error-handler

https://www.npmjs.com/package/express-body-parser-error-handler

for example:

const bodyParserErrorHandler = require('express-body-parser-error-handler')
const { urlencoded, json } = require('body-parser')
const express = require('express')
const app = express();
router.route('/').get(function (req, res) {
    return res.json({message:"🚀"});
});

// body parser initilization
app.use('/', json({limit: '250'}));

// body parser error handler
app.use(bodyParserErrorHandler());
app.use(router);
...

Solution 9 - Javascript

(bodyParser, req, res) => new Promise((resolve, reject) => {
    try {
        bodyParser(req, res, err => {
            if (err instanceof Error) {
                reject(err);
            } else {
                resolve();
            }
        });
    } catch (e) {
        reject(e);
    }
})

Bullet-proof. Future-aware. WTFPL-Licensed. And also useful w/ async/await.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGabriel LlamasView Question on Stackoverflow
Solution 1 - JavascriptrobertklepView Answer on Stackoverflow
Solution 2 - JavascriptDaniel PérezView Answer on Stackoverflow
Solution 3 - JavascriptGabriel LlamasView Answer on Stackoverflow
Solution 4 - JavascriptErick GarciaView Answer on Stackoverflow
Solution 5 - Javascriptsunmonu oluwoleView Answer on Stackoverflow
Solution 6 - JavascriptdudkoView Answer on Stackoverflow
Solution 7 - Javascriptuser3721143View Answer on Stackoverflow
Solution 8 - JavascriptNaor TedgiView Answer on Stackoverflow
Solution 9 - JavascriptAlexander Aleksandrovič KlimovView Answer on Stackoverflow