🧊

EventEmitterのerrorイベントのハマりどころ

1年に1回くらいハマる(主に人の書いたコードのデバッグで)し、毎回自分の記事検索して見つからなくて困ってるので、今度こそメモっておく。

これは去年の様子。

TL;DR

`EventEmitter`継承クラス作るのはいいけど、`emit('error')`しないで!`emit('err')`とか別の名前にして!

error はただの文字列ではない

Events | Node.js v11.10.0 Documentation

まあ型的にはもちろん文字列なんやけど、特別な意味を持ってる。

すごく簡単に説明すると、`emit('error', err)`は`throw err`と同じ。
なので`catch`してないならそこでプロセスが即終了する。

パターンとしては2つのハマりどころがある。

  • `emit('error')` してるコードを書いてないのに、`on('error')`が呼ばれる
  • `on('error')`せずに`emit('error')`して、例外エラーで落ちる

emit('error')してないのにon('error')

これは、その`EventEmitter`継承クラスのどっかの処理で、例外が起きてる + `catch`されてないとき。

例外処理が漏れてるせいで、意図的に発火してるであろう`error`イベントの中に、マジモンの`error`イベントが混ざってしまう。

混ぜたいなら別に良いけど、ほとんどはそんなことないはずなので、`err`とか`xxx-error`とかなんでもいいけど別のイベント名にする。

on('error')せずにemit('error')

これは、もはや自分で`throw`してるのと同じ。

SDKとかでありがちで、よかれと思って`error`イベントを通知しようとして使ったらプロセスごと落ちるやつ。

これも落としたいなら別に良いけど、そうでないなら別のイベント名にする。