捕捉快递中的所有错误不起作用

时间:2012-09-23 18:30:45

标签: error-handling express

我想为所有未单独处理的错误服务一个error.ejs文件。

当我从mongoose user.save()收到重复键错误时,此代码不执行任何操作 http://expressjs.com/guide.html#error-handling

app.js

app.use(function(err, req, res, next){
  res.status(500);
  res.render('error', { error: "Woops, we encountered an error..." });
});

路由/ index.js

user.save(function(err){
    if ( err ) throw err;
});

以下示例给出了此错误:捕获异常:[ReferenceError:next未定义]

user.save(function(err){
    if ( err ) next(err);
});

2 个答案:

答案 0 :(得分:1)

您的代码段

user.save(function(err){
    if ( err ) next(err);
});

大概是在一个有功能(req,res)的路线里面?

您需要做的是该功能的“下一步”

function MyRoute( req, res, next ) {
  user.save(function(err){
    if ( err ) 
      return next(err);

    // carry on here doing whatever
  });
}

app.get('/some/route', MyRoute);

答案 1 :(得分:-1)

您可以围绕所有请求处理程序创建一个包装函数,以捕获异步错误而不会导致服务器崩溃。

这仍然只捕获异步/承诺错误,而不是未承诺的节点 API(例如:setTimeout 或 fs)

function errorSafeRequestHandler (
  /** @type {Promise<import("express-serve-static-core/index").RequestHandler>} */ requestHandler,
) {
  return async function (
    /** @type {import("express-serve-static-core/index").Request} */ req,
    /** @type {import("express-serve-static-core/index").Response} */ res,
    /** @type {import("express-serve-static-core/index").NextFunction} */ next,
  ) {
    try {
      return await requestHandler(req, res, next)
    } catch (err) {
      // either pass on any errors to the registered error handeler
      next(err)
      // // or handle it right here:
      // console.log(err)
      // res.status(500).send()
    }
  }
}

现在使用 errorSafeRequestHandeler 函数包装所有请求处理程序

// instead of:
app.get('/danger/route', async (req, res) => {
  Promise.reject(new Error('Crashes server'))
});

// use:
app.get('/safer/route', errorSafeRequestHandeler(async (req, res) => {
  await Promise.reject(new Error('Doesn\'t crash server'))
  Promise.reject(new Error('Doesn\'t crash server'))
  fs.writeFile(path.join('path', data) // Errors here don't crash server

  // can still crash using some node api's:
  setTimeout(() => Promise.reject(new Error('Crashes server')), 1000)
  (async () => {
    fs.writeFile(path.join('path', data) // Errors here crash server
  })()

}));