bun/no-unhandled-emitter-errors
Require an error listener on event emitters that Node.js functions return
When an event emitter emits error and nobody listens for it, the error is thrown instead. A try around the call doesn't catch it, because it happens later. So spawn("gti") with a typo, or createReadStream() on a file that's gone, ends the whole process.
The rule looks at what these functions return:
| Module | Functions |
|---|---|
node:child_process | spawn, fork |
node:cluster | fork |
node:fs | createReadStream, createWriteStream, watch |
node:http, node:https | request, get |
node:http2, node:tls | connect |
node:net | connect, createConnection |
Configure#
Off by default. To turn it on:
bunfig.toml
[lint.rules]
"bun/no-unhandled-emitter-errors" = "error" # or "warn"Every option, set to its default:
bunfig.toml
[lint.rules]
"bun/no-unhandled-emitter-errors" = ["error", {
factories = [], # list of objects
}]Examples#
example.js1 problem
import { spawn } from "node:child_process";
const child = spawnspawn() emits error when it fails, which crashes the process if nothing listens. Add an error listener.("git", ["status", "--short"]);
child.stdout.on("data", show);
child.on("exit", done);pipe() doesn't pass errors on, so the source still needs a listener:
example.js1 problem
import { createReadStream } from "node:fs";
createReadStreamcreateReadStream() emits error when it fails, which crashes the process if nothing listens. Add an error listener.(file).pipe(response);example.jsNo problems
import { spawn } from "node:child_process";
const child = spawn("git", ["status", "--short"]);
child.stdout.on("data", show);
child.on("exit", done);
child.on("error", fail);example.jsNo problems
import { createReadStream } from "node:fs";
createReadStream(file).on("error", fail).pipe(response);An emitter that's returned, exported or passed to another function isn't reported, because the listener might be added there. pipeline() handles its streams' errors:
example.jsNo problems
import { createReadStream } from "node:fs";
import { pipeline } from "node:stream/promises";
await pipeline(createReadStream(file), response);
export function open(path) {
return createReadStream(path);
}
export const log = createReadStream("app.log");Options#
| Option | Default | What it does |
|---|---|---|
factories | [] | More functions that return an emitter, checked in addition to the table above. Each entry is { module, names }, with the import specifier and the function names. Without names, the default export is the function. |
bunfig.toml
[lint.rules]
"bun/no-unhandled-emitter-errors" = ["error", {
factories = [{ module = "ws", names = ["createWebSocketStream"] }],
}]example.jswith
{ "factories": [{ "module": "ws", "names": ["createWebSocketStream"] }] }1 problemimport { createWebSocketStream } from "ws";
const stream = createWebSocketStreamcreateWebSocketStream() emits error when it fails, which crashes the process if nothing listens. Add an error listener.(socket);
stream.on("data", show);