美文网首页
【管子先生的Node之旅·10】Node的错误处理

【管子先生的Node之旅·10】Node的错误处理

作者: 管子先生 | 来源:发表于2017-10-28 17:57 被阅读0次

错误处理

众所周知Node 应用是依托在一个拥有大量共享状态的进程中,所以只要里面有错误而且还未及捕获,那么恭喜你,准备加班吧。
先举个栗子,看一下下面的代码:

    var http = require('http');

    var serv = http.createServer(function() {
        throw new Error('错误未捕获');
    });

    serv.listen(3010);

错误未及时捕获,程序直接崩溃:

image.png
从错误输出,你可以看到调用堆栈从事件轮询一路到回调函数。Node 之所以会这样处理,主要是因为在发生未捕捉的错误时,进程就会变得不确定。之后可能就无法正常工作了,如果始终不处理的话,就会一直抛出意料之外的错误,这样就很难调试了。
可以通过添加uncaughtException 处理器,可以全部捕获未被捕获的 err,此时你可以针对不同错误进行不同操作了。
    process.on('uncaughtException', function(err) {
        console.log(err); //打印出错误
        console.log(err.stack); //打印出错误的调用栈方便调试
        process.exit(1); //手动退出进程
    });

Node 中,许多像httpnet 这样的原生模块都会分发error事件。如果该事件未处理,才会抛出未处理的异常。并且绝大多数的Node 异步Api 接受回调函数,第一个参数就是error 或者 null

堆栈追踪

在JavaScript中,当发生错误时,控制台会打印出来一些错误信息,这些信息就被成为堆栈追踪
先举个栗子看一下:

    function a() {
        b();
    }

    function b() {
        c();
    }

    function c() {
        throw new Error('手动错误');
    }

    a();

下面你可以清楚的看到导致错误发送执行函数的路径。


image.png

下面我们引入事件轮询看一下:

    function c() {
        setTimeout(function() {
            throw new Error('手动错误');
        }, 1000)
    }

堆栈中一些有用的信息就丢失了。

image.png
所以,要捕获一个未来才执行到的函数错误是不可能的。这会直接抛出未捕获到的错误,例如如下的catch
代码是永远不会执行到的:
    try{
        setTimeout(function(){
            throw new Error('手动错误');
        },1000);
    }catch(err){
        console.log(err);
    }

这就是为什么在Node.js中,每一步操作都需要正确的进行错误处理的原因了。

相关文章

网友评论

      本文标题:【管子先生的Node之旅·10】Node的错误处理

      本文链接:https://www.haomeiwen.com/subject/jmlspxtx.html