express 中的错误处理

node中错误处理

node中抛出一个uncaughtException应该要让node进程直接结束。而不是通过process.on('uncaughtException',handler)进行统一处理。

如果真要全局捕获错误,可以像下面这样处理:

process
  .on('unhandledRejection', (reason, p) => {
    console.error(reason, 'Unhandled Rejection at Promise', p);
  })
  .on('uncaughtException', err => {
    console.error(err, 'Uncaught Exception thrown');
    process.exit(1);
  });

不过这样并没多大的必要。我们可以使用pm2来管理node。每次遇到uncaughtException时,直接让node进程挂掉,pm2会自动帮我们重启node并将错误记录下来,这样方便以后我对程序的修复。

unhandledRejection是未被处理的Promise rejection。建议所有的Promise最后都要用catch方法进行处理。否则unhandledRejection的异常信息下面会提示如下:

DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

大意:未被处理的promise rejection已经被弃用。未来,未被处理的promise rejection会直接以非0的exit code来结束node进程(正常结束的exit code是0,非0的exit code表示非正常结束)。

参考:

Catch all uncaughtException for Node js app

express请求内的错误处理

express中内置了一个错误处理程序。如果请求内的同步代码抛出异常或调用next(err),那么 Express 会将当前请求视为处于错误状态,并跳过所有剩余的非错误处理路由和中间件函数,最后被内置的错误处理程序处理。

我们可以自定义一个错误处理中间件函数,它比普通的中间件函数多了一个err参数,而且一般我们将这个中间件放在所有中间件的后面。例子:

app.use(function(err, req, res, next) {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

这样我们就可以对请求内的错误进行统一处理。

http-errors

http-errors包能根据传入的http状态码,生成对应的HTTP error。

let error=createError(404); // 生成http 404状态码的error
let error=createError(500); // 生成http 500状态码的error

http-errors生成的error继承Error,所以可以通过error.message error.name error.stack分别获得错误的信息,名称,还有栈。同时它还多了一个error.status,该字段是http状态码。

http-errors配合express错误处理中间件函数使用会很方便。例子:

const createError = require("http-errors");

// ...

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  let error = createError(404);
  next(error);
});

// error handler
app.use(function(err, req, res, next) {
  let result =
    process.env.NODE_ENV === "development"
      ? {
          error: {
            message: err.message,
            name: error.name,
            stack: err.stack
          }
        }
      : {};

  res.status(err.status || 500);
  res.json(result);
});

参考:

错误处理

日志

使用pm2管理node服务时,console.error会被输出到错误日志内,console.log会被输出到自定义日志内。再配合morgan包,可以将用户的访问信息记录到访问日志内。

服务器长期运行的情况下,日志文件会越来越大,我们可以让运维写定时任务将每个日志按天甚至按小时拆分,这样不仅可以减小文件的大小,还能方便我们查阅。

总结

  • 不要对全局未捕获的异常进行统一处理,而应当让node进程直接crash掉,利用pm2进行进程守护与错误日志输出。
  • 要对每个promise的rejection进行处理。
  • express内置错误处理程序,它可以对请求内的同步异常和next(err)传递的异常进行处理。我们也可以自定义错误处理中间件函数,来覆盖内置错误处理程序。
  • 使用http-errors配合自定义错误处理程序。
  • 使用pm2输出错误日志和自定义日志,使用morgan包输出访问日志。

你可能感兴趣的:(node)