错误处理和断言处理
- try/catch只能处理同步方法中抛出的错误
- uncaughtException,粗暴简单,容易导致内存泄露和资源泄露
- domain模块
- assert模块
domain模块
- 程序任何时刻抛出错误都可通知Domain对象,让它处理
- run(fn)中的fn内的一切继承宇EventEmitter对象的对象都隐式地绑定到了Domain对象上
var http = require('http');
var domain = require('domain');
http.createServer(function(req, res) {
var d = domain.create();
d.once('error', function(err) {
res.writeHead(200,{"contentType":"text/plain"});
res.end("error");
});
//被监听的代码写在run内
d.run(function() {
if(req.url != '/favicon.ico') {
nonnext(); //这里发生未定义错误
//下面不会被执行到
console.log(req.headers)
res.writeHead(200,{"contentType":"text/plain"});
res.end("ok");
}
});
}).listen(8080);
显式绑定
var http = require('http');
var domain = require('domain');
function cd() {
throw new Error("err")
}
http.createServer(function(req, res) {
var d = domain.create();
d.add(req); //显式绑定
d.add(res); //显式绑定
d.bind(cb); //显式绑定
d.on('error', function(err) {
res.writeHead(200,{"contentType":"text/plain"});
res.end("error");
});
req.on('data', function(chunk) {
console.log(chunk)
nonxe(); //未定义的错误
res.writeHead(200,{"contentType":"text/plain"});
res.write("some data");
});
req.on("end", function() {
res.end("ok");
})
}).listen(8080);
Domain的堆栈
var http = require('http');
var domain = require('domain');
var d1 = domain.create();
d1.name = "d1";
var d2 = domain.create();
d2.name = "d2";
d1.on('error', function(err) {
console.log('d1 catch error');
console.log(domain._stack)
})
d2.on('error', function(err) {
console.log('d2 catch error');
console.log(domain._stack)
})
console.log('original stack:');
console.log(domain._stack);
d1.run(function() {
console.log('after running domain 1:');
console.log(domain._stack);
d2.run(function() {
console.log('after running domain 2:');
console.log(domain._stack);
throw new Error("error");
})
})
堆栈情况及d2 catch error
original stack:
[]
after running domain 1:
[ Domain {
domain: null,
_events: { error: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
members: [],
name: 'd1' } ]
after running domain 2:
[ Domain {
domain: null,
_events: { error: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
members: [],
name: 'd1' },
Domain {
domain: null,
_events: { error: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
members: [],
name: 'd2' } ]
d2 catch error
修改一点点
d1.run(function() {
console.log('after running domain 1:');
console.log(domain._stack);
d2.run(function() {
console.log('after running domain 2:');
console.log(domain._stack);
d1.enter();//让d1加入栈顶
throw new Error("error");
})
})
结果d1 catch error
original stack:
[]
after running domain 1:
[ Domain {
domain: null,
_events: { error: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
members: [],
name: 'd1' } ]
after running domain 2:
[ Domain {
domain: null,
_events: { error: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
members: [],
name: 'd1' },
Domain {
domain: null,
_events: { error: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
members: [],
name: 'd2' } ]
d1 catch error
最外层的domain弹出栈时,内嵌套的domains都将被弹出
d1.run(function() {
console.log('after running domain 1:');
console.log(domain._stack);
d2.run(function() {
console.log('after running domain 2:');
console.log(domain._stack);
d1.exit(); //外层的d1退出,整个栈弹出
throw new Error("error");
})
})
F:\后台开发\node-server-test\errorHandler.js:23
throw new Error("error");
^
Error: error
at Domain.<anonymous> (F:\后台开发\node-server-test\errorHandler.js:23:15)
at Domain.run (domain.js:242:14)
at Domain.<anonymous> (F:\后台开发\node-server-test\errorHandler.js:19:8)
at Domain.run (domain.js:242:14)
at Object.<anonymous> (F:\后台开发\node-server-test\errorHandler.js:16:4)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
销毁Domain对象
d.dispose()