Javascript 如何在Restify中间件中捕获未处理的承诺拒绝?
我正在Node.js上编写一个Restify应用程序。我需要一个函数,当Restify回调中发生错误时调用它。此函数应向客户端发送响应。如果我没有使用承诺或异步函数,我可以这样做:Javascript 如何在Restify中间件中捕获未处理的承诺拒绝?,javascript,node.js,promise,async-await,restify,Javascript,Node.js,Promise,Async Await,Restify,我正在Node.js上编写一个Restify应用程序。我需要一个函数,当Restify回调中发生错误时调用它。此函数应向客户端发送响应。如果我没有使用承诺或异步函数,我可以这样做: server.on('uncaughtException', (req, res, route, err) => { log.error(err); res.send(err); }); 但是如果我的回调是async函数,则不会调用函数中的异常,而是引发unhandledPromiserRejecti
server.on('uncaughtException', (req, res, route, err) => {
log.error(err);
res.send(err);
});
但是如果我的回调是async
函数,则不会调用函数中的异常,而是引发unhandledPromiserRejection
我如何重构我的代码,使其能够像处理常见错误一样处理未处理的承诺拒绝
是的,我知道我可以检查Restify中间件本身内部的错误,但它仍然使代码更复杂,更容易编写
if (!core.validateUUID(req.params.deviceId)) {
throw new Error(`Device ${req.params.deviceId} is wrong`)
}
然后
我为此挣扎了一段时间,我想出了一个简单的解决方案。我创建了一个简单的包装函数,它包装路由处理程序/中间件,并在承诺中运行代码。这样,未处理的拒绝和未捕获的异常可以通过相同的回调进行处理:
// your error general handler
function errorResponse(req, res, err) { ... }
/**
* When using promises inside handler, you need to return the Promise from it to allow proper rejection handling
*
* @param {Function} callback with `req`, `res` and `next` parameters
* @returns {Function}
*/
function catcher(callback) {
return (req, res, next) => {
Promise
.resolve()
.then(() => callback(req, res, next))
.catch(err => errorResponse(req, res, err));
};
}
// use it like this
server.use(catcher(middleware1));
server.post(catcher(postRoute));
server.get(catcher(getRoute));
在处理程序中使用承诺时,您需要从处理程序返回承诺,以允许正确的拒绝处理。您不能只侦听“unhandledRejection”事件吗?请参阅:@mattdommond我可以,但这样我将无法获得
req
和res
对象,我需要res
对象将错误详细信息返回给用户。令人难以置信的是,在2020年Restify
中没有捕捉到承诺拒绝中的错误
// your error general handler
function errorResponse(req, res, err) { ... }
/**
* When using promises inside handler, you need to return the Promise from it to allow proper rejection handling
*
* @param {Function} callback with `req`, `res` and `next` parameters
* @returns {Function}
*/
function catcher(callback) {
return (req, res, next) => {
Promise
.resolve()
.then(() => callback(req, res, next))
.catch(err => errorResponse(req, res, err));
};
}
// use it like this
server.use(catcher(middleware1));
server.post(catcher(postRoute));
server.get(catcher(getRoute));