Javascript Catch-express-bodyParser错误

Javascript Catch-express-bodyParser错误,javascript,node.js,express,Javascript,Node.js,Express,我想在发送json对象时捕获bodyParser()中间件的错误,该错误无效,因为我想发送自定义响应,而不是一般错误 这就是我所拥有的,它是有效的: app.use (express.bodyParser ()); app.use (function (error, req, res, next){ //Catch bodyParser error if (error.message === "invalid json"){ sendError (res, myC

我想在发送json对象时捕获bodyParser()中间件的错误,该错误无效,因为我想发送自定义响应,而不是一般错误

这就是我所拥有的,它是有效的:

app.use (express.bodyParser ());
app.use (function (error, req, res, next){
    //Catch bodyParser error
    if (error.message === "invalid json"){
        sendError (res, myCustomErrorMessage);
    }else{
        next ();
    }
});
但在我看来,这是一种非常丑陋的方法,因为我正在比较可能在未来的express版本中更改的错误消息。有没有其他方法可以捕获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
}
{
堆栈:“错误:无效json\n位于Object.exports.Error(/node\u modules/express/node\u modules/connect/lib/utils.js:55:13)\n位于IncomingMessage。(/node\u modules/express/node\u modules/connect/lib/middleware/json.js:74:71)\n位于IncomingMessage.events.js:92:17)\n在_stream_readable.js:872:14\n在进程中。_tickDomainCallback(node.js:459:13)',
参数:未定义,
类型:未定义,
消息:“无效json”,
现状: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)
错误:无效的json
在Object.exports.error(/node_modules/express/node_modules/connect/lib/utils.js:55:13)
在收到消息时。(/node_modules/express/node_modules/connect/lib/middleware/json.js:74:71)
在IncomingMessage.EventEmitter.emit(events.js:92:17)
在_stream_readable.js:872:14
在进程中。_tickDomainCallback(node.js:459:13)

我认为最好的办法是检查语法错误:

好的,找到了:

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


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

if (err instanceof SyntaxError &&
  err.status >= 400 && err.status < 500 &&
  err.message.indexOf('JSON') !== -1) {
    // process filtered exception here
}
if(语法错误实例)&&
err.status>=400&&err.status<500&&
err.message.indexOf('JSON')!=-1){
//在此处理筛选的异常
}

防弹的。未来意识。WTFPL许可。还有一个有用的w/async/await。

来自@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();
}
我所做的只是:

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()
  }
})
创建新模块“hook body parser.js” 在这里用body解析器钩住所有东西

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 }),
  ];
};
像这样使用over express

。。。 app.use(hookBodyParser())

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

这不起作用,因为它不是语法错误。请参阅问题更新。@Gabriellamas使用最新版本的Express(4.6.1)
bodyParser
模块不再是内置的,它已经被移动到自己的模块中,这确实会为格式错误的JSON抛出一个
SyntaxError
。但是,如果请求正文太大,您将得到一个错误而不是一个SyntaxError。例如:
{[Error:request entity too large]键入:'entity.too.large',消息:'request entity too large',statusCode:413,status:413,预期值:322350,长度:322350,限制:102400}
只需检查
语法错误实例
,然后检查
错误实例
,或者对它们进行相同的处理。问题:如果在解析JSON时发生任何错误,
error
将是truthy,否则将是false-y,对吗?@WillBrickner
error
将始终是truthy,只有在发生错误时才会调用处理程序。但是错误可以是任何东西,它是一个通用的Express错误处理程序。这不是一个解决方案。在这段代码成为另一个中间件之前,您没有考虑到这一点。如果您以这种方式捕获某些异常,则可能导致不可预测的状态。至少最好编写:
app.use(function(error,req,res,next){/*Shutdown node*/};app.use(bodyParser.json());app.use(function(error,req,res,next){/*如果err.status==4**,那么handle json error=>res.status(400.send(),否则Shutdown node*/})
DANGER-DANGER,正如@Dao所说,这会捕获上述中间件中的任何错误。此后,我将如何将此函数作为中间件插入我的应用程序?我将实际响应错误的代码放在何处?这是做什么的?请解释如何将其集成到express应用程序中,以及它是如何工作的。您好,非常清楚,但是否有缩短的方法?是否需要验证参数?我不确定,也许我会再看一看文档,看看是否有缩短
indexOf
使用的方法是错误的。如果在javascript中找不到真实的
-1
,它将返回
-1
。唯一不起作用的方法是如果
JSON
是字符串中的第一个。应该是
err.message.indexOf('JSON')!=-1
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()
  }
})
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(function (error, req, res, next) {
if (error.type === 'entity.parse.failed') {
 sendError(res, myCustomErrorMessage);
} else {
 next();
}
});