一、同步异常处理
//app.js
/**
* 同步异常处理
*/
app.use(function errorHandler(err, req, res, next) {
var accept = accepts(req);
var type = accept.type('html', 'json', 'text');
var jsonResult = new JsonResult();
jsonResult.status = -1;
jsonResult.message = "系统繁忙";
logger.error('synchronous error on request %s %s: %s', req.method, req.url, err.message);
if(err.domain) {
logger.error("attention!!!, this is an unhandled error,please solve this problem as soon as possible!!!");
}
if(type === "json") {
var contentType = res.get("Content-Type");
//Content-Type为空,认为系统还没有处理过异常,这里进行处理
if(!contentType) {
var jsonResult = new JsonResult();
jsonResult.status = -1;
jsonResult.message = "系统繁忙";
res.json(jsonResult);
}
} else {
res.send(500, "系统繁忙");
}
});
app.use(errorHandler({ dumpExceptions: true, showStack: true }));
二、异步异常处理
//app.js
app.use(require('express-domain-middleware'));
var domain = require('domain');
app.use(function (req, res, next) {
//https://nodejs.org/api/domain.html#domain_domain
//引入一个domain的中间件,将每一个请求都包裹在一个独立的domain中
//domain来处理异步异常
var d = domain.create();
//监听domain的错误事件
d.on('error', function (err) {
logger.error('asynchronous error on request %s %s: %s', req.method, req.url, err.message);
var contentType = res.get("Content-Type");
//Content-Type为空,认为系统还没有处理过异常,这里进行处理
if(!contentType) {
var jsonResult = new JsonResult();
jsonResult.status = -1;
jsonResult.message = "系统繁忙";
res.json(jsonResult);
}
//d.dispose();//释放一个domain对象 'domain.dispose() is deprecated
});
d.add(req);
d.add(res);
d.run(next);
});
三、最终的异常处理
/**
*落网的异常最后到了这里
*/
process.on('uncaughtException', function (err) {
console.error('serious error happend: ' + err);
});
四、try catch
nodejs中大部分异常都是异步的,然try catch并不能捕获异步的异常。。。
五、关键点
使用过promise框架的人都知道promise框架本身也可以进行异常处理监听,如果方法已经对异常进行了处理的话就没必要再公共异常处理进行异常处理了,这里通过contentType来判断各自的方法是否已经对异常进行了处理,判断的依据就是是否设置了contentType。
六、memcached 和redis操作的异常处理
setTimeout(function () {
throw new Error("dsf");
}, 100);
如果是memcached 和redis的异常处理,必须使用setTimeOut才能捕获到异常,这是domain的一个大坑。