Node.js错误处理和断言处理

错误处理和断言处理

  • 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()

2. assert模块

猜你喜欢

转载自blog.csdn.net/w_bu_neng_ku/article/details/80113579