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中内置了一个错误处理程序。如果请求内的同步代码抛出异常或调用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
包,可以将用户的访问信息记录到访问日志内。
服务器长期运行的情况下,日志文件会越来越大,我们可以让运维写定时任务将每个日志按天甚至按小时拆分,这样不仅可以减小文件的大小,还能方便我们查阅。
next(err)
传递的异常进行处理。我们也可以自定义错误处理中间件函数,来覆盖内置错误处理程序。http-errors
配合自定义错误处理程序。morgan
包输出访问日志。