2

我有一条路线,首先需要查询数据库,然后使用结果查询另一个 Web 服务,然后使用该结果呈现页面。我已经解决了这个流程,并试图找出错误处理。鉴于我与多个服务人员交谈,我试图在返回错误之前对其进行按摩。

以下是路线的代码结构:

Models.Episode.findById(request.params.episodeID)
    .catch(function (error) {
        throw (throwjs.notFound());
    })
    .then(function (episode) {
        if (episode.getUser().id !== request.user.href) {
            return next(throwjs.unauthorized("You do not have access to this podcast"));
        }
        return doSomeOtherAsyncStuff();
    })
    .then(function (queryResponse) {
        renderPage();
    })
    .catch(function (error) {
        next(error);
    });

我的问题是第一次捕获。我在这个 catch 中的目标是重新打包错误并停止执行并将错误发送到 express 中间件。

用上面写的方式,执行停止,但我的快速错误处理程序没有被调用。

我尝试将第一个捕获重写为

.catch(function(error){
     return next(error);
})

但这并不能解决问题。我找到的唯一解决方案是将捕获移动到最后。但后来我失去了故障位置的上下文。

关于我做错了什么的任何线索?谢谢,奥利维尔

4

2 回答 2

2

I'd recommend taking a different approach so you don't have to rely on long running promise chains. With the following approach, you've decoupled your authorization and and validation to separate middleware, since they're not necessarily a concern of the actual episode handler itself. Plus this approach is more idiomatic to express.

An added bonus is that you're free to pass errors down to an error handler so you further decouple your errors from your route handlers.

function validateEpisode(req, res, next) {
  Models.Episode
    .findById(req.params.episodeID)
    .then(function(episode) {
      req.yourApp.episode = episode;
      next() // everything's good
    })
    .catch(function(error) {
      // would be better to pass error in next
      // so you can have a general error handler
      // do something with the actual error
      next(throwjs.notFound());
    });
}

function authUserByEpisode(req, res, next) {
  if (req.yourApp.episode.getUser().id !== req.user.href) {
    next(throwjs.unauthorized("You do not have access to this podcast"));
  }

  next(); // authorized
}

function episodeController(req, res) {
  // do something with req.yourApp.episode
}

app.get('/episode/:id', validateEpisode, authUserByEpisode, episodeController)
于 2016-06-15T17:26:12.553 回答
0

毕竟,这与我正在使用的 throwjs 框架以及我使用不正确的事实有关

    throw (throwjs.notFound());

应该

    throw (new throwjs.notFound());

...

于 2016-06-10T14:13:56.987 回答