Node.js 处理 EventEmitter handler 中抛出的异常的奇怪姿势

官方文档中提到有一个 “error” 特殊的 event

https://nodejs.org/api/events.html#events_error_events

const myEmitter = new MyEmitter();
myEmitter.on('error', (err) => {
  console.error('whoops! there was an error');
});
myEmitter.emit('error', new Error('whoops!'));
// Prints: whoops! there was an error

其实就是一个约定好的事件,捕捉到的错误让你都往里面扔而已。如果callback function中出现了异常没有手动捕获的话还是会导致崩溃的,没什么乱用。

const EventEmitter = require('events');

const emitter = new EventEmitter();

setInterval(() => {}, 1 << 30); // Keep process alive

emitter.on('error', err => {
  console.error('error caught', err);
})

emitter.on('test', () => {
  throw new Error('Opps');
});

emitter.emit('test');
// index.js:20
//   throw new Error('Opps');
//   ^

// Error: Opps

那就需要自己构建一个函数了,手动捕捉错误然后emit “error” event。

const makeHandler = (func, emitter) => async (...args) => {
  try {
    await func(...args);
  } catch (error) {
    emitter.emit('error', error);
  }
}

传入 handler function和emitter实例,捕捉到错误后扔到"error" event里去。

emitter.on('error', err => {
  console.error('error caught', err);
})

emitter.on('test', makeHandler(() => {
  throw new Error('Opps');
}, emitter));

emitter.emit('test');

// error caught Error: Opps

这样就可以捕捉到错误了, 给async function也可以。
当然也可以写成 extend class

import EventEmitter from 'events';

export default class ErrorHandledEventEmitter extends EventEmitter {
  makeHandler = func => async (...args) => {
    try {
      await func(...args);
    } catch (error) {
      this.emit('error', error);
    }
  }
}
const myEmitter = new ErrorHandledEventEmitter();

myEmitter.on('error', error => {
  console.error('error caught', error);
});

myEmitter.on('test', myEmitter.makeHandler(() => {
  throw new Error('Opps');
}));

myEmitter.emit('test');

你可能感兴趣的:(Node.js 处理 EventEmitter handler 中抛出的异常的奇怪姿势)