Files
scriptc/tests/corpus/writable-error-callbacks.ts
T
Chris Tate b8e678b765 Evaluate a drain name expression, and discard a write callback's return value
events.once(process.stdout, name) with a name typed "drain" returned the
pending promise without evaluating the name, so a call or comma
expression producing "drain" never ran. A name that is not a string
literal now runs before the promise is created.

A write completion callback that returns a value (`() => count++`, a
stored function typed `(): number`) reported SC2020. The stream ignores
the return value, so such a callback is adapted to return nothing, as
before the error-argument form was added.

The stream-shims npm case compiles and matches Node now that write
callbacks take the error argument, so its SC2020 expectation is removed.
2026-10-29 14:48:45 -05:00

67 lines
2.2 KiB
TypeScript

// Writable.write completion callbacks that take the error argument: null
// after a successful write, the _write failure, ERR_STREAM_WRITE_AFTER_END
// after end(), and ERR_STREAM_DESTROYED after destroy(). Node orders the
// callback and the 'error' event through its writable state machine; this
// program prints both.
import { Writable } from "node:stream";
function show(label: string): (error?: Error | null) => void {
return (error) => {
const code = error ? (error as NodeJS.ErrnoException).code : undefined;
console.log(
label,
error === null ? "null" : error === undefined ? "undefined" : `${code ?? ""} ${error.message}`,
);
};
}
const sink = new Writable({
write(chunk: Buffer, _encoding: string, callback: (error?: Error | null) => void): void {
callback(chunk.toString() === "bad" ? new Error("rejected") : null);
},
});
sink.on("error", (error) => console.log("error event", error.message));
sink.write("good", show("good"));
sink.write("bad", show("bad"));
const ended = new Writable({
write(_chunk: Buffer, _encoding: string, callback: (error?: Error | null) => void): void {
callback();
},
});
ended.on("error", (error) =>
console.log("ended error event", (error as NodeJS.ErrnoException).code),
);
ended.write("first", show("first"));
ended.end();
ended.write("late", show("late"));
const destroyed = new Writable({
write(_chunk: Buffer, _encoding: string, callback: (error?: Error | null) => void): void {
callback();
},
});
destroyed.destroy();
destroyed.write("after destroy", show("destroyed"));
// A callback declared without parameters keeps its current lowering.
const plain = new Writable({
write(_chunk: Buffer, _encoding: string, callback: () => void): void {
callback();
},
});
plain.write("x", () => console.log("plain done"));
// Callbacks that return a value: the stream discards it.
let count = 0;
const counted = (): number => ++count;
plain.write("y", counted);
const tally = (error?: Error | null): number => (error ? -1 : ++count);
const counting = new Writable({
write(_chunk: Buffer, _encoding: string, callback: (error?: Error | null) => void): void {
callback(null);
},
});
counting.write("tally", tally);
setTimeout(() => console.log("count", count), 5);