summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/dts/lib.deno.ns.d.ts6
-rw-r--r--cli/tests/unit/write_file_test.ts36
-rw-r--r--runtime/js/40_write_file.js10
3 files changed, 51 insertions, 1 deletions
diff --git a/cli/dts/lib.deno.ns.d.ts b/cli/dts/lib.deno.ns.d.ts
index b0c56591b..8aa478f12 100644
--- a/cli/dts/lib.deno.ns.d.ts
+++ b/cli/dts/lib.deno.ns.d.ts
@@ -1714,6 +1714,12 @@ declare namespace Deno {
create?: boolean;
/** Permissions always applied to file. */
mode?: number;
+ /**
+ * An abort signal to allow cancellation of the file write operation.
+ * If the signal becomes aborted the writeFile operation will be stopped
+ * and the promise returned will be rejected with an AbortError.
+ */
+ signal?: AbortSignal;
}
/** Synchronously write `data` to the given `path`, by default creating a new
diff --git a/cli/tests/unit/write_file_test.ts b/cli/tests/unit/write_file_test.ts
index 4c4cecf43..c4c437708 100644
--- a/cli/tests/unit/write_file_test.ts
+++ b/cli/tests/unit/write_file_test.ts
@@ -239,3 +239,39 @@ unitTest(
assertEquals("Hello", actual);
},
);
+
+unitTest(
+ { perms: { read: true, write: true } },
+ async function writeFileAbortSignal(): Promise<void> {
+ const ac = new AbortController();
+ const enc = new TextEncoder();
+ const data = enc.encode("Hello");
+ const filename = Deno.makeTempDirSync() + "/test.txt";
+ queueMicrotask(() => ac.abort());
+ try {
+ await Deno.writeFile(filename, data, { signal: ac.signal });
+ } catch (e) {
+ assertEquals(e.name, "AbortError");
+ }
+ const stat = Deno.statSync(filename);
+ assertEquals(stat.size, 0);
+ },
+);
+
+unitTest(
+ { perms: { read: true, write: true } },
+ async function writeFileAbortSignalPreAborted(): Promise<void> {
+ const ac = new AbortController();
+ ac.abort();
+ const enc = new TextEncoder();
+ const data = enc.encode("Hello");
+ const filename = Deno.makeTempDirSync() + "/test.txt";
+ try {
+ await Deno.writeFile(filename, data, { signal: ac.signal });
+ } catch (e) {
+ assertEquals(e.name, "AbortError");
+ }
+ const stat = Deno.statSync(filename);
+ assertEquals(stat.size, 0);
+ },
+);
diff --git a/runtime/js/40_write_file.js b/runtime/js/40_write_file.js
index def9f6fee..6ced4e066 100644
--- a/runtime/js/40_write_file.js
+++ b/runtime/js/40_write_file.js
@@ -13,6 +13,9 @@
data,
options = {},
) {
+ if (options?.signal?.aborted) {
+ throw new DOMException("The write operation was aborted.", "AbortError");
+ }
if (options.create !== undefined) {
const create = !!options.create;
if (!create) {
@@ -68,12 +71,17 @@
await chmod(path, options.mode);
}
+ const signal = options?.signal ?? null;
let nwritten = 0;
- while (nwritten < data.length) {
+ while (!signal?.aborted && nwritten < data.length) {
nwritten += await file.write(TypedArrayPrototypeSubarray(data, nwritten));
}
file.close();
+
+ if (signal?.aborted) {
+ throw new DOMException("The write operation was aborted.", "AbortError");
+ }
}
function writeTextFileSync(