diff --git a/src/runtime/webcore/blob/Store.rs b/src/runtime/webcore/blob/Store.rs index 15130252fdbc..d3a7ed83c97b 100644 --- a/src/runtime/webcore/blob/Store.rs +++ b/src/runtime/webcore/blob/Store.rs @@ -230,7 +230,7 @@ impl FileExt for File { None, )) } - PathOrFileDescriptor::Fd(_) => Ok(JSPromise::resolved_promise_value( + PathOrFileDescriptor::Fd(_) => Ok(JSPromise::rejected_promise( cx.global(), // `JSGlobalObject::create_invalid_args` lives in the still-gated // `JSGlobalObject.rs`; `ERR_INVALID_ARG_TYPE` (lib.rs) is the @@ -238,7 +238,8 @@ impl FileExt for File { cx.global().ERR_INVALID_ARG_TYPE(format_args!( "Is not possible to unlink a file descriptor" )), - )), + ) + .to_js()), } } } diff --git a/test/js/web/fetch/blob-write.test.ts b/test/js/web/fetch/blob-write.test.ts index 02d3111eb98b..2a45f53546af 100644 --- a/test/js/web/fetch/blob-write.test.ts +++ b/test/js/web/fetch/blob-write.test.ts @@ -1,4 +1,5 @@ import { expect, test } from "bun:test"; +import { closeSync, openSync } from "fs"; import { expectMaxObjectTypeCount, tempDir, tempDirWithFiles } from "harness"; import path from "path"; @@ -55,6 +56,23 @@ test("Bun.file(path).delete() does not throw", async () => { expect(await Bun.file(path.join(dir, "a")).exists()).toBe(false); }); +// A file made from a descriptor has no path to unlink. +test.each(["unlink", "delete"] as const)("Bun.file(fd).%s() rejects", async method => { + await using dir = tempDir("bun-unlink-fd", { a: "Hello, world!" }); + const fd = openSync(path.join(dir, "a"), "r"); + try { + const promise = Bun.file(fd)[method](); + await expect(promise).rejects.toBeInstanceOf(TypeError); + await expect(promise).rejects.toMatchObject({ + code: "ERR_INVALID_ARG_TYPE", + message: "Is not possible to unlink a file descriptor", + }); + } finally { + closeSync(fd); + } + expect(await Bun.file(path.join(dir, "a")).exists()).toBe(true); +}); + test("blob.writer() throws for data-backed blob", () => { const blob = new Blob(["Hello, world!"]) as any; expect(() => blob.writer()).toThrowErrorMatchingInlineSnapshot(