express.js 4: 在路由器的 errorHandler 中捕获 bodyParser 错误
express.js 4: catch bodyParser error in router's errorHandler
如何在 express.js 4 中捕获路由器错误处理程序中的 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;
向 /test
发送空主体的 POST
请求将 return testRouter error: not implemented
。此消息来自 testRouter
中定义的错误处理程序,这是我期望发生的情况。
但是,向 /test
发送一个 POST
请求并带有格式错误的 json 正文将 return default error handler: [bodyParser error]
。此消息来自默认错误处理程序。
我希望 testRouter
中的错误处理程序能够处理对 /test
的请求中发生的所有 bodyParser 错误。我怎样才能做到这一点?
您需要 testRouter
使用主体解析器中间件:
// not this:
app.use(bodyParser.json());
// but this:
testRouter.use(bodyParser.json());
否则默认路由器将处理错误,就像您注意到的那样。
如果您还想为默认路由器使用主体解析器中间件,请确保在您添加testRouter
:
app.use('/test', testRouter);
app.use(bodyParser.json());
是我的问题的答案,如何在路由器的 errorHandler 中捕获 bodyParser 错误。然而,我发现了一个稍微不同的解决方案 without catching the error inside the router。我的基本想法是,我想将与 /api/v1.0
下公开的 api 相关的所有内容放入 javascript 模块中的路由器中——包括一个错误处理程序,它以api。因此我在 app.js
中有以下行:
app.use('/api/v1.0', require('./routes/api/v1.0/api'));
api.js
导出一个 express.Router()
。该路由器永远不会处理来自路由器 'outside' 的错误。 (另请参阅 GitHub 个问题 catch error of "toplevel" app.use-middlewear in router error handler #2679 and Inconsistent 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 的错误。
如何在 express.js 4 中捕获路由器错误处理程序中的 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;
向 /test
发送空主体的 POST
请求将 return testRouter error: not implemented
。此消息来自 testRouter
中定义的错误处理程序,这是我期望发生的情况。
但是,向 /test
发送一个 POST
请求并带有格式错误的 json 正文将 return default error handler: [bodyParser error]
。此消息来自默认错误处理程序。
我希望 testRouter
中的错误处理程序能够处理对 /test
的请求中发生的所有 bodyParser 错误。我怎样才能做到这一点?
您需要 testRouter
使用主体解析器中间件:
// not this:
app.use(bodyParser.json());
// but this:
testRouter.use(bodyParser.json());
否则默认路由器将处理错误,就像您注意到的那样。
如果您还想为默认路由器使用主体解析器中间件,请确保在您添加testRouter
:
app.use('/test', testRouter);
app.use(bodyParser.json());
/api/v1.0
下公开的 api 相关的所有内容放入 javascript 模块中的路由器中——包括一个错误处理程序,它以api。因此我在 app.js
中有以下行:
app.use('/api/v1.0', require('./routes/api/v1.0/api'));
api.js
导出一个 express.Router()
。该路由器永远不会处理来自路由器 'outside' 的错误。 (另请参阅 GitHub 个问题 catch error of "toplevel" app.use-middlewear in router error handler #2679 and Inconsistent 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 的错误。