1年に1回くらいハマる(主に人の書いたコードのデバッグで)し、毎回自分の記事検索して見つからなくて困ってるので、今度こそメモっておく。
EventEmitterで error イベント投げるとそれだけでthrowされんのしらんかった・・・https://t.co/NtYwccI5BV
— りぃ (@leader22) 2018年1月11日
これは去年の様子。
TL;DR
`EventEmitter`継承クラス作るのはいいけど、`emit('error')`しないで!`emit('err')`とか別の名前にして!
error はただの文字列ではない
まあ型的にはもちろん文字列なんやけど、特別な意味を持ってる。
すごく簡単に説明すると、`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`イベントを通知しようとして使ったらプロセスごと落ちるやつ。
これも落としたいなら別に良いけど、そうでないなら別のイベント名にする。