Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/js/internal/fs/cp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const { chmod, copyFile, lstat, mkdir, opendir, readlink, stat, symlink, unlink,
const { dirname, isAbsolute, join, parse, resolve, sep } = require("node:path");

const PromisePrototypeThen = $Promise.prototype.$then;
const PromiseReject = Promise.$reject;
const PromiseReject = Promise.$reject.bind(Promise);
const ArrayPrototypeFilter = Array.prototype.filter;
const StringPrototypeSplit = String.prototype.split;
const ArrayPrototypeEvery = Array.prototype.every;
Expand Down
2 changes: 1 addition & 1 deletion src/js/internal/primordials.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const arrayToSafePromiseIterable = (promises, mapFn) =>
new Promise((a, b) => PromisePrototypeThen.$call(mapFn == null ? promise : mapFn(promise, i), a, b)),
),
);
const PromiseAll = Promise.all;
const PromiseAll = Promise.all.bind(Promise);
Comment thread
robobun marked this conversation as resolved.
const PromiseResolve = Promise.$resolve.bind(Promise);
const SafePromiseAll = (promises, mapFn) => PromiseAll(arrayToSafePromiseIterable(promises, mapFn));
const SafePromiseAllReturnArrayLike = (promises, mapFn) =>
Expand Down
2 changes: 1 addition & 1 deletion src/js/node/readline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const {

const internalGetStringWidth = $newZigFunction("string.zig", "String.jsGetStringWidth", 1);

const PromiseReject = Promise.$reject;
const PromiseReject = Promise.$reject.bind(Promise);

var isWritable;

Expand Down
20 changes: 20 additions & 0 deletions test/js/node/readline/readline_promises.node.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,26 @@ describe("readline/promises.createInterface()", () => {
assert.strictEqual(closed, true);
});

// https://github.com/oven-sh/bun/issues/30939
// rl.question() with a pre-aborted signal used to throw "TypeError: |this|
// is not an object" because PromiseReject was captured as an unbound
// Promise.$reject reference. The rejection must carry the AbortError, not
// a TypeError masking it.
it("question() with pre-aborted signal rejects with AbortError", async () => {
const fi = new FakeInput();
// @ts-ignore
const rl = new readlinePromises.Interface({ input: fi, output: fi });
const ac = new AbortController();
ac.abort();
// @ts-ignore
const result = await rl.question("x", { signal: ac.signal }).then(
() => ({ ok: true }),
err => ({ name: err?.name, message: err?.message }),
);
rl.close();
expect(result).toEqual({ name: "AbortError", message: "The operation was aborted." });
});

it("should support Symbol.dispose as alias for close()", () => {
const fi = new FakeInput();
let closed = false;
Expand Down
25 changes: 25 additions & 0 deletions test/js/node/stream/node-stream.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,31 @@ it("Readable.fromWeb", async () => {
expect(Buffer.concat(chunks).toString()).toBe("Hello World!\n");
});

// https://github.com/oven-sh/bun/issues/30939
// Multiple queued writes on a Transform.fromWeb stream trigger _writev, which
// internally calls SafePromiseAll. Promise.all must be bound in primordials;
// otherwise this throws "TypeError: |this| is not an object".
it("Transform.fromWeb _writev does not throw on buffered writes", async () => {
const s = Transform.fromWeb(new TransformStream());
const chunks = [];
s.on("data", chunk => chunks.push(chunk));
const { promise, resolve, reject } = Promise.withResolvers();
s.on("end", resolve);
s.on("error", reject);

// Five synchronous writes force the writable side to queue and coalesce
// into a single _writev call.
s.write(Buffer.from("hello"));
s.write(Buffer.from("hello"));
s.write(Buffer.from("hello"));
s.write(Buffer.from("hello"));
s.write(Buffer.from("hello"));
s.end();

await promise;
expect(Buffer.concat(chunks).toString()).toBe("hellohellohellohellohello");
});

it("#9242.5 Stream has constructor", () => {
const s = new Stream({});
expect(s.constructor).toBe(Stream);
Expand Down
Loading