Linter · Rules
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
Reported:
import { spawn } from "node:child_process";
const child = spawn("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:
import { createReadStream } from "node:fs";
createReadStream(file).pipe(response);
Not reported:
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);
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:
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"] }],
}]
import { createWebSocketStream } from "ws";
const stream = createWebSocketStream(socket);
stream.on("data", show);