猫鼬错误不会从路由器到应用程序

Mongoose errors doesn't raise from router to app

有一个 api 应用程序是这样的:

const express = require('express')
const app = express()
const router = require('express').Router()
...
route.post('/dogs', (req, res, next) => {
  const dog = new Dog() // it defined in real app
  dog.validate() // error happens here
    .then(() => {
      return res.status(201)
    })
    // [1]
})
...
app.use('/api/v1', router)
app.use(notFoundErrorHandler)
app.use(globalErrorHandler)

function notFoundErrorHandler (req, res, next) {
  res.status(404)
  res.send({error: 'Not found'})
}

function globalErrorHandler (err, req, res, next) {
  if (err) {
    res.status(err.status || 500)
    res.json({error: err.message || err})
  }
}

如果存在验证错误,它不会传递给 globalErrorHandler,但捕获并重新抛出错误可以解决问题 [1]:

.catch(err => { return next(err) })

这种行为对于未完全实现 Promise 的猫鼬来说是否正常,或者可以通过其他方式实现?

使用savefind等其他方法时不会报错

这很正常,是的,与 mongoose 无关,但与 Express 无关。 Express 不会隐式处理未处理的异常,您必须显式处理它们。因此,在每条路线中,您都必须捕获任何错误并将它们传递给 next.

我知道这有时会令人沮丧,所以我建议您创建一个路由管理器,它会为每个路由注册一个动作处理程序和一个 try/catch 模式。

有很多例子,这里是我喜欢的一个简单的例子。

 var dogHandler = require('dogHandler')

 var serverRoutes = [{
     path: "dogs",
     method: "post",
     action: dogHandler
 }]

 serverRoutes.forEach(route => {
     app[route.method](route.path, (request, response, next) => {
         route.action(request, response)
             .then(() => next)
             .catch(err => next(err));
     });
 });