Javascript 如何在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

我正在Node.js上编写一个Restify应用程序。我需要一个函数,当Restify回调中发生错误时调用它。此函数应向客户端发送响应。如果我没有使用承诺或异步函数,我可以这样做:

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