美文网首页我爱编程程序员
Node.js ERROR 带你快速理解 Node.js 的错误

Node.js ERROR 带你快速理解 Node.js 的错误

作者: 小菜荔枝 | 来源:发表于2018-02-08 14:08 被阅读0次

    ERROR简介

    Node.js 的错误分为四类:

    • 标准 JavaScript 错误,如 EvalErrorSynctaxErrorRangeErrorReferenceErrorTypeErrorURIError
    • 系统错误,如通过程序我们想打开一个文件,但是系统中不存在这个文件,就会抛出系统错误
    • 通过程序代码 throw() 抛出的错误
    • 断言错误,通过模块 assert 抛出的错误

    同步API和异步API

    Node.js的API主要有两种风格,同步和异步,如何区分呢,大部分异步API一般都有一个回调函数 callback 作为其参数,而大部分同步API则不会,例如:

    // 异步 API
    const fs = require('fs');
    fs.readFile('/etc/passwd', (err, data) => {
      if (err) console.log(err);
      else console.log(data);
    });
    
    // 同步 API
    fs.readFileSync('/etc/passwd');
    

    Node.js 风格的回调

    Node.js 大部分的异步方法都接受一个回调函数作为参数,我们通过该回调函数的第一个参数来判断是否发生了错误,如果是 null,则没有发生错误,如果不是 null,则调用该方法出现了错误,我们管这种回调叫做 Node.js 风格的回调

    const fs = require('fs');
    
    fs.readFile('/some/file/that/does-not-exist', function(err, data){
      if (err) {
        console.error('There was an error', err);
        return;
      }
      console.log(data);
    });
    

    注意:如果想在异步方法的回调函数里面抛出错误,不要放在 try / catch 代码块中,这样不仅不会捕获到异常,而且未捕获的异常可能会造成程序停止

    // 这样不会捕获异常:
    const fs = require('fs');
    
    try {
      fs.readFile('/some/file/that/does-not-exist', (err, data) => {
        // mistaken assumption: throwing here...
        if (err) {
          throw err; // 抛出错误,但是无法被捕获到
        }
      });
    } catch (err) {
      // 无法被捕获到
      console.error(err);
    }
    

    因回调函数还没有执行,try / catch 代码已经执行完毕并退出,所以无法捕获错误。如果想捕获错误,可以使用 process.on('uncaughtException') (或者 Domain 模块来处理,但 Domain 模块已被新版本弃用,这里只是提一嘴,不推荐使用)方法来处理,可以把上面的代码改造成:

    const fs = require('fs');
    
    fs.readFile('/some/file/that/does-not-exist', (err, data) => {
        // mistaken assumption: throwing here...
        if(err) {
            throw err; 
        }
    });
    
    process.on('uncaughtException', (err) => {
        console.log(err);
    })
    

    错误传播和拦截

    Node.js 支持多种机制来处理应用程序运行时发生的错误。如何处理这些错误完全取决于错误的类型和被调用的 API 的风格,所有的 JavaScript 错误和大部分同步 API 都用 try / catch 机制处理:

    const fs = require('fs');
    try {
      const m = 1;
      const n = m + z; // javaScript 错误
      fs.readFileSync('./test.js');  // 同步API
    } catch (err) {
      // 在这处理错误
    }
    

    异步 API 分为两种处理方式:一种是 Node.js 回调风格的 API,前面已有介绍另一种方式:如果一个对象是一个 EventEmitter 时,如 StreamEvent 等模块,调用这个对象的异步方法时可以通过这个对象的 error 事件处理:

    const net = require('net');
    const connection = net.connect('localhost'); // EventEmitter
    
    // 绑定 error 事件
    connection.on('error', (err) => {
      // 处理 err
      console.error(err);
    });
    
    connection.pipe(process.stdout);
    

    注意:如果不用 error 事件处理,我们的程序将会崩溃,该错误也可以用 process.on('uncaughtException') 来捕获

    CLASS Error

    Node.js 的错误机制不会解释为什么会发生错误,它只会通过追踪栈信息来尽可能的描述该错误

    new Error(message)

    创建一个 Error 实例,message 是个字符串,也可以是一个对象(如果是对象,则 Node.js 先会把这个对象转化成字符串,再调用 new Error(message)

    Error.captureStackTrace(targetObject[, constructorOpt])

    targetObject 对象设置一个 stack 属性,记录 targetObject 的追踪栈信息,constructorOpt是一个函数,如果传了该参数,则该参数会在追踪栈信息中隐藏:

    function MyError() {
      Error.captureStackTrace(this, MyError); // MyError会在结果中隐藏
    }
    new MyError().stack;
    
    Error.stackTraceLimit

    追踪栈信息的条数,默认值是 10,可以设置为其他值,如果设置的不是数字或者是负数,则不会追踪任何栈信息

    Error Object
    • error.code 错误码,参照 Node.js Error Codes
    • error.message 错误信息
    • error.stack 追踪栈信息
    try {
      Error.stackTraceLimit = 15;
      const m = z++;
    } catch (e) {
      console.log(e.stack);
    }
    // ReferenceError: z is not defined
    //   at Object.<anonymous> (C:\Users\papa_\.WebStorm2017.3\config\consoles\ide\ide-scripting.js:78:13)
    //   at Module._compile (module.js:635:30)
    //   at Object.Module._extensions..js (module.js:646:10)
    //   at Module.load (module.js:554:32)
    //   at tryModuleLoad (module.js:497:12)
    //   at Function.Module._load (module.js:489:3)
    //   at Function.Module.runMain (module.js:676:10)
    //   at startup (bootstrap_node.js:187:16)
    //   at bootstrap_node.js:608:3
    
    • C:\Users\papa_\.WebStorm2017.3\config\consoles\ide\ide-scripting.js:78:13 带有有绝对路径的一般表示用户程序的调用
    • module.js:635:30 没有绝对路径的一般表示 Node.js 的调用
    • native 一个方法描述一般表示 V8 引擎的调用

    结语:本文介绍了 Node.js 的错误异常处理机制,跟原生JS还是有很大的差别,合理的处理 ERROR 会使我们的程序更健壮也会让开发人员更容易地确定问题并解决;原文档中有关系统错误做了详细的说明,因为跟 linux 的系统错误类似,在这就不做解释了;大部分异步同步 API 的处理方式都是与本文所述一致的的,但有一些特殊的 API 可能处理的方式不同,使用的时候请查阅文档

    简书作者 小菜荔枝原创 转载请联系作者获得授权

    相关文章

      网友评论

        本文标题:Node.js ERROR 带你快速理解 Node.js 的错误

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