Express异步/等待错误处理程序中的动态响应状态

时间:2019-02-14 11:59:41

标签: javascript node.js express

我想用异步/等待替换Express路由中的promise链。这使代码更干净,更易读。首先看一下我的代码。

我以前有过:

app.post('/search', (req,res) => {
    sendRequest(req.body).then( searchDetails => {
        res.send(searchDetails);
    }).catch( error => {
        res.status(404).send(error)
    });
});

当前代码:

app.post('/search', asyncMiddleware(async (req,res) => {
    const result = await sendRequest(req.body);
    res.send(result);
}));

asyncMiddleware的外观如下:

const asyncMiddleware = checkedFunction => (req, res) => {
    Promise
        .resolve(
            checkedFunction(req, res)
        )
        .catch( error => {
            res.status(400).send(error)
        });
};

当我的路由包含多个错误状态时,问题就开始了。

app.delete('/delete/:id', authenticate, (req, res) => {
    const id = req.params.id;

    if (!ObjectID.isValid(id)) {
      return res.status(404).send();
    }

    User.findOneAndDelete({
        _id: id,
        _user: req.user._id
    }).then((todo) => {
      if (!todo) {
        return res.status(404).send();
      }

      res.send({todo});
    }).catch((e) => {
      res.status(400).send();
    });
});

如何使asyncMiddleware返回状态取决于错误?

1 个答案:

答案 0 :(得分:1)

asyncMiddleware此处检查checkedFunction(即快速路由处理程序)是否已发生或故意抛出了任何错误。如果您想对asyncMiddleware说些什么,则需要像对/search一样用它包装您的路由处理程序,那么您需要抛出涉及错误信息的特定错误/对象:

app.delete('/delete/:id', authenticate, asyncMiddleware(async (req, res) => {
    const id = req.params.id;

    if (!ObjectID.isValid(id)) {
      throw {
          status: 404,
          message: 'id not valid'
      }
    }

    try {
        const todo = await User.findOneAndDelete({
            _id: id,
            _user: req.user._id
        });

        if (!todo) {
            throw {
                status: 404,
                message: 'todo not found'
            }
        }
        res.send({todo});
    } catch (e) {
        throw {
            status: 400,
            message: 'mongodb error'
        }
    }
}));

然后asyncMiddleware可以发送状态作为响应

const asyncMiddleware = checkedFunction => (req, res) => {
    Promise
        .resolve(
            checkedFunction(req, res)
        )
        .catch( error => {
            res.status(error.status).send(error.message)
        });
};

您可以创建内置Error对象而不是自定义对象来跟踪错误调用堆栈,但我认为您不需要在这里。