59

我想在发送 json 对象时从 bodyParser() 中间件中捕获错误,但它无效,因为我想发送自定义响应而不是通用 400 错误。

这就是我所拥有的并且它有效:

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

但在我看来,这似乎是一种非常丑陋的方法,因为我正在比较可能在未来快速版本中更改的错误消息。还有其他方法可以捕获 bodyParser() 错误吗?

编辑:

这是请求正文具有无效 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
}

漂亮的印刷堆栈:

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)
4

9 回答 9

27

我认为你最好的选择是检查SyntaxError

app.use(function (error, req, res, next) {
  if (error instanceof SyntaxError) {
    sendError(res, myCustomErrorMessage);
  } else {
    next();
  }
});
于 2013-04-04T18:57:56.577 回答
24

来自@alexander的回答,但有一个使用示例

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();
}
于 2018-02-15T17:38:53.480 回答
7

好的,找到了:

bodyParser() 是 json()、urlencoded() 和 multipart() 的便捷函数。我只需要调用 json(),捕获错误并调用 urlencoded() 和 multipart()。

bodyParser 源码

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 ());
于 2013-04-04T19:14:51.687 回答
6

我所做的只是:

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()
  }
})
于 2020-05-13T21:02:21.453 回答
3

所有错误都包括从 1.18.0 版本开始的类型属性。对于解析失败,err.type === 'entity.parse.failed'。

app.use(function (error, req, res, next) {
if (error.type === 'entity.parse.failed') {
 sendError(res, myCustomErrorMessage);
} else {
 next();
}
});
于 2021-03-04T07:46:41.070 回答
1

我发现检查SyntaxError是不够的,因此我这样做:

if (err instanceof SyntaxError &&
  err.status >= 400 && err.status < 500 &&
  err.message.indexOf('JSON') !== -1) {
    // process filtered exception here
}
于 2017-01-10T11:38:59.290 回答
0

创建新模块“hook-body-parser.js”在这里用body parser钩住所有东西

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 }),
  ];
};

并像这样使用过度快递

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

于 2021-02-09T05:46:34.560 回答
0

如果您想捕获 body-parsr 抛出的所有错误,例如 entity.too.largeencoding.unsupported

只需在 body-parser 初始化之后放置这个中间件

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

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

例如:

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);
...
于 2021-12-25T07:21:42.467 回答
-3
(bodyParser, req, res) => new Promise((resolve, reject) => {
    try {
        bodyParser(req, res, err => {
            if (err instanceof Error) {
                reject(err);
            } else {
                resolve();
            }
        });
    } catch (e) {
        reject(e);
    }
})

防弹。面向未来。WTFPL 许可。并且对 w/async/await 也很有用。

于 2018-01-07T14:42:30.797 回答