关于node.js:NodeJS错误处理

5次阅读

共计 2607 个字符,预计需要花费 7 分钟才能阅读完成。

前言

最近在公司的 Koa.js 我的项目中遇到一个问题,应用 thrift 库创立一个 connection,在接口中应用该连贯的 client 来发送申请,后果抛错连贯失败且中断了程序的执行,用 try/catch 无奈捕捉到该谬误。遂查看创立连贯的源码,发现 Connection 构造函数中有如下代码:

var Connection = exports.Connection = function(stream, options) {
  var self = this;
  EventEmitter.call(this);
  
  this.connection = stream;
  
  // ... 其余代码
  
  this.connection.addListener("error", function(err) {
    // Only emit the error if no-one else is listening on the connection
    // or if someone is listening on us, because Node turns unhandled
    // 'error' events into exceptions.
    if (self.connection.listeners('error').length === 1 ||
        self.listeners('error').length > 0) {self.emit("error", err);
    }
  });
  
  // ... 其余代码
}

正文翻译:只有在没有人监听连贯或有人监听咱们(this)时才收回谬误,因为 Node 会将未解决的“谬误”事件变成异样。

Node 错误处理

同步 API

除了多数例外,同步的 API(任何不承受 callback 函数的阻塞办法,例如 fs.readFileSync)都应用 throw 来报告谬误。任何应用 JavaScript throw 机制都会引发异样,必须应用 try…catch 解决,否则 Node.js 过程将立刻退出。

try {throw new Error('something error');
} catch(e) {// 解决 error}

异步 API

当你应用 try/catch 尝试捕捉异步操作中的谬误时,会发现无奈捕捉到

try {setTimeout(() => {throw new Error('something error');
  }, 1000);
} catch(e) {console.log(e);
}
// 执行后果
// Uncaught Error: something error
//     at <anonymous>:3:11

异步的 API 中产生的谬误能够以多种形式报告:

  • 大多数承受 callback 函数的异步办法将承受作为第一个参数传给该函数的 Error 对象。如果第一个参数不是 null 并且是 Error 的实例,则产生了应该解决的谬误。

    const fs = require('node:fs');
    fs.readFile('a file that does not exist', (err, data) => {if (err) {console.error('There was an error reading the file!', err);
        return;
      }
      // 否则解决数据
    });
  • 当在 EventEmitter 对象上调用异步办法时,谬误能够路由到该对象的 'error' 事件。

    const net = require('node:net');
    const connection = net.connect('localhost');
    
    // 向流中增加 'error' 事件句柄:connection.on('error', (err) => {
      // 如果连贯被服务器重置,// 或者根本无法连贯,或者连贯遇到任何类型的谬误,// 则谬误将发送到这里。console.error(err);
    });
    
    connection.pipe(process.stdout);
  • Node.js API 中的一些典型的异步办法可能依然应用 throw 机制来引发必须应用 try…catch 解决的异样。

留神 :应用async/await 解决异步函数时,应应用同步函数的 try/catch 来解决。

对于所有的 EventEmitter 对象,如果未提供 'error' 事件句柄,则将抛出谬误,导致 Node.js 过程报告未捕捉的异样并解体,除非:domain 模块应用切当或已为 'uncaughtException'事件注册句柄。

EventEmitter

EventEmitter 是 Node.js 的内置模块 events 提供的一个类,它的外围就是事件触发与事件监听器性能的封装。通过 require("events"); 来拜访该模块:

const {EventEmitter} = require('event');
let eventEmitter = new EventEmitter();

提供了以下办法:

  • addListener(event, listener) 为指定事件增加一个监听器到监听器数组的尾部。
  • on(event, listener) 为指定事件注册一个监听器,承受一个字符串 event 和一个回调函数。
  • once(event, listener) 为指定事件注册一个单次监听器,即 监听器最多只会触发一次,触发后立即解除该监听器。
  • removeListener(event, listener) 移除指定事件的某个监听器,监听器必须是该事件曾经注册过的监听器。它承受两个参数,第一个是事件名称,第二个是回调函数名称。
  • removeAllListeners([event]) 移除所有事件的所有监听器,如果指定事件,则移除指定事件的所有监听器。
  • setMaxListeners(n) 默认状况下,EventEmitters 如果你增加的监听器超过 10 个就会输入正告信息。setMaxListeners 函数用于扭转监听器的默认限度的数量。
  • listeners(event) 返回指定事件的监听器数组。
  • emit(event, [arg1], [arg2], […]) 按监听器的程序执行执行每个监听器,如果事件有注册监听返回 true,否则返回 false。

问题起因及解决方案

因为没有在 connection 上增加额定的 error 监听,所以 self.emit("error", err); 会执行,然而没有对应的 listener,就导致了未捕捉的异样,导致 node 中断执行。故只须要在 createConnection 创立的对象上监听 error 事件即可。

参考:

谬误的流传和拦挡

浅谈前端中的错误处理

正文完
 0