错误的冒泡和捕捉


    所有的 JavaScript 错误都是作为异常处理的,立即产生并通过标准的 JavaScript throw 机制抛出错误。这些都是利用 JavaScript 语言提供的 处理的。

    JavaScript 的 throw 机制在任何时候使用都会引发异常,必须通过 try / catch 处理,否则 Node.js 会立即退出进程。

    但也有少数例外,同步的 API(任何不接受 callback 函数的阻塞方法,例如,fs.readFileSync)会使用 throw 报告错误。

    • 大多数的异步方法都接受一个 callback 函数,该函数接受给其第一个参数传递一个 Error 对象。如果第一个参数不是 null 或是一个 Error 实例,就应该对发生的错误进行处理。
    1. const fs = require('fs');
    2. fs.readFile('a file that does not exist', (err, data) => {
    3. if (err) {
    4. console.error('There was an error reading the file!', err);
    5. return;
    6. }
    7. // Otherwise handle the data
    8. });
    • 在 Node.js API 中有一小部分普通的异步方法仍可能使用 throw 机制引发错误,必须使用 try / catch 处理。这些方法并没有一个完整的列表。请参阅各类方法的文档以确定所需的合适的错误处理机制。

    大多数的 和 event emitter-based API 都使用相同的 'error' 事件机制,它们本身就代表了一系列随着时间推移的异步操作(相对于单一操作,可能有效也可能无效)。

    对于所有EventEmitter 对象而言,如果不能提供一个 'error' 事件处理程序,那么错误将被抛出,从而导致 Node.js 进程报告一个未处理的异常并随即崩溃,除非适当的使用 模块或已经注册了 process.on(‘uncaughtException’) 事件。

    1. const EventEmitter = require('events');
    2. const ee = new EventEmitter();
    3. setImmediate(() => {
    4. // This will crash the process because no 'error' event
    5. // handler has been added.
    6. ee.emit('error', new Error('This will crash'));
    7. });

    在调用的代码退出后抛出的错误,不能通过 try / catch 截获。

    大多数由 Node.js 核心 API 暴露出来的异步方法都遵循称之为“Node.js 风格的回调”的惯用模式。通过这种模式,可以用作为参数的方法传递函数。当操作完成或引发错误时,Error 对象(无论如何)都会作为第一个参数被回调函数所调用。如果没有引发错误,第一个参数会作为 null 传递。

    1. // THIS WILL NOT WORK:
    2. const fs = require('fs');
    3. try {
    4. fs.readFile('/some/file/that/does-not-exist', (err, data) => {
    5. // mistaken assumption: throwing here...
    6. if (err) {
    7. throw err;
    8. }
    9. });
    10. } catch (err) {
    11. // This will not catch the throw!
    12. console.log(err);
    13. }

    这并没有什么用,因为 fs.readFile() 是一个异步调用的回调函数。当回调函数被调用时,这些代码(包括 try { } catch(err) { } 区域)就已经退出。在大对数案例中,抛出回调函数中的错误会引起 Node.js 进程崩溃。如果被启用,或已注册了 process.on(‘uncaughtException’) 事件,那么这样的错误是可以被拦截的。