2

如何在 express.js 4 的路由器的 errorHandler 中捕获 bodyParser 错误?

示例代码:

var express = require('express');
var bodyParser = require('body-parser');

var app = express();

// use bodyParser.json()
app.use(bodyParser.json());

// setup route /test
var testRouter = express.Router();
testRouter.post('/', function(req, res, next) {
  next(new Error('not implemented'));
});
testRouter.use('/', function(err, req, res, next) {
  res.send('testRouter error: ' + err.message);
});
app.use('/test', testRouter);

// default error handler
app.use(function(err, req, res, next) {
  res.send('default error handler: ' + err.message);
});

module.exports = app;

使用空正文发送POST请求将返回。此消息来自 中定义的错误处理程序,这是我期望发生的。/testtestRouter error: not implementedtestRouter

但是,使用格式错误的 json 正文发送POST请求/test将返回default error handler: [bodyParser error]. 此消息来自默认错误处理程序。

我希望 中的错误处理程序处理testRouter/test. 我怎样才能做到这一点?

4

2 回答 2

2

您需要testRouter使用正文解析器中间件:

// not this:
app.use(bodyParser.json());

// but this:
testRouter.use(bodyParser.json());

否则,默认路由器将处理错误,就像您注意到的那样。

如果您还想为默认路由器使用正文解析器中间件,请确保在添加testRouter声明它:

app.use('/test', testRouter);
app.use(bodyParser.json());
于 2015-06-16T17:25:46.177 回答
1

robertklep 的答案是我的问题的答案,即如何在路由器的 errorHandler 中捕获 bodyParser 错误。但是,我发现了一个稍微不同的解决方案,而没有发现路由器内部的错误。我的基本想法是,我想将与暴露在下面的 api 相关的所有内容/api/v1.0放入 javascript 模块中的路由器中 - 包括以 api 所需格式输出错误的错误处理程序。因此,我有以下行app.js

app.use('/api/v1.0', require('./routes/api/v1.0/api'));

api.js导出一个express.Router(). 该路由器永远不会处理来自路由器“外部”的错误。(另请参阅 GitHub 问题catch error of "toplevel" app.use-middlewear in router error handler #2679Inconsistent behavior with error-handling middleware in routers #2633)。

要使用特定于 api 的错误处理程序捕获所有错误,必须将 api 路由器和 api 错误处理程序分开。可以这样做:

api.js

var express = require('express');
var router = express.Router();

router.use('/endpoint', require('./endpoint'));

var errorHandler = function (err, req, res, next) {
  // all errors need to be returned in json
  res.status(err.status || 500);
  res.json({ error: err.message });
};

module.exports.router = router;
module.exports.errorHandler = errorHandler;

app.js

var api = require('./routes/api/v1.0/api');
app.use('/api/v1.0', api.router);
app.use('/api/v1.0', api.errorHandler);

这样,api 的错误处理程序仍然只处理对 的请求/api/v1.0,但可以捕获所有错误,包括来自定义为应用程序级中间件的 bodyParser 的错误。

于 2015-06-16T22:59:31.630 回答