mirror of
https://github.com/denoland/deno.git
synced 2025-09-29 21:54:48 +00:00
feat: support abort reasons in Deno APIs and WebSocketStream
(#13066)
This commit is contained in:
parent
9ffc7edc23
commit
01a6b66034
9 changed files with 241 additions and 63 deletions
49
cli/tests/testdata/websocketstream_test.ts
vendored
49
cli/tests/testdata/websocketstream_test.ts
vendored
|
@ -1,9 +1,11 @@
|
|||
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
import {
|
||||
assert,
|
||||
assertEquals,
|
||||
assertRejects,
|
||||
assertThrows,
|
||||
unreachable,
|
||||
} from "../../../test_util/std/testing/asserts.ts";
|
||||
|
||||
Deno.test("fragment", () => {
|
||||
|
@ -89,8 +91,49 @@ Deno.test("aborting immediately throws an AbortError", async () => {
|
|||
controller.abort();
|
||||
await assertRejects(
|
||||
() => wss.connection,
|
||||
DOMException,
|
||||
"connection was aborted",
|
||||
(error: Error) => {
|
||||
assert(error instanceof DOMException);
|
||||
assertEquals(error.name, "AbortError");
|
||||
},
|
||||
);
|
||||
await assertRejects(
|
||||
() => wss.closed,
|
||||
(error: Error) => {
|
||||
assert(error instanceof DOMException);
|
||||
assertEquals(error.name, "AbortError");
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
Deno.test("aborting immediately with a reason throws that reason", async () => {
|
||||
const controller = new AbortController();
|
||||
const wss = new WebSocketStream("ws://localhost:4242", {
|
||||
signal: controller.signal,
|
||||
});
|
||||
const abortReason = new Error();
|
||||
controller.abort(abortReason);
|
||||
await assertRejects(
|
||||
() => wss.connection,
|
||||
(error: Error) => assertEquals(error, abortReason),
|
||||
);
|
||||
await assertRejects(
|
||||
() => wss.closed,
|
||||
(error: Error) => assertEquals(error, abortReason),
|
||||
);
|
||||
});
|
||||
|
||||
Deno.test("aborting immediately with a primitive as reason throws that primitive", async () => {
|
||||
const controller = new AbortController();
|
||||
const wss = new WebSocketStream("ws://localhost:4242", {
|
||||
signal: controller.signal,
|
||||
});
|
||||
controller.abort("Some string");
|
||||
await wss.connection.then(
|
||||
() => unreachable(),
|
||||
(e) => assertEquals(e, "Some string"),
|
||||
);
|
||||
await wss.closed.then(
|
||||
() => unreachable(),
|
||||
(e) => assertEquals(e, "Some string"),
|
||||
);
|
||||
await assertRejects(() => wss.closed, DOMException, "connection was aborted");
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
assertRejects,
|
||||
assertThrows,
|
||||
pathToAbsoluteFileUrl,
|
||||
unreachable,
|
||||
} from "./test_util.ts";
|
||||
|
||||
Deno.test({ permissions: { read: true } }, function readFileSyncSuccess() {
|
||||
|
@ -95,11 +96,52 @@ Deno.test(
|
|||
async function readFileWithAbortSignal() {
|
||||
const ac = new AbortController();
|
||||
queueMicrotask(() => ac.abort());
|
||||
await assertRejects(async () => {
|
||||
await assertRejects(
|
||||
async () => {
|
||||
await Deno.readFile("cli/tests/testdata/fixture.json", {
|
||||
signal: ac.signal,
|
||||
});
|
||||
},
|
||||
(error: Error) => {
|
||||
assert(error instanceof DOMException);
|
||||
assertEquals(error.name, "AbortError");
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
Deno.test(
|
||||
{ permissions: { read: true } },
|
||||
async function readFileWithAbortSignalReason() {
|
||||
const ac = new AbortController();
|
||||
const abortReason = new Error();
|
||||
queueMicrotask(() => ac.abort(abortReason));
|
||||
await assertRejects(
|
||||
async () => {
|
||||
await Deno.readFile("cli/tests/testdata/fixture.json", {
|
||||
signal: ac.signal,
|
||||
});
|
||||
},
|
||||
(error: Error) => {
|
||||
assertEquals(error, abortReason);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
Deno.test(
|
||||
{ permissions: { read: true } },
|
||||
async function readFileWithAbortSignalPrimitiveReason() {
|
||||
const ac = new AbortController();
|
||||
queueMicrotask(() => ac.abort("Some string"));
|
||||
try {
|
||||
await Deno.readFile("cli/tests/testdata/fixture.json", {
|
||||
signal: ac.signal,
|
||||
});
|
||||
});
|
||||
unreachable();
|
||||
} catch (e) {
|
||||
assertEquals(e, "Some string");
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
assertRejects,
|
||||
assertThrows,
|
||||
pathToAbsoluteFileUrl,
|
||||
unreachable,
|
||||
} from "./test_util.ts";
|
||||
|
||||
Deno.test({ permissions: { read: true } }, function readTextFileSyncSuccess() {
|
||||
|
@ -88,11 +89,52 @@ Deno.test(
|
|||
async function readTextFileWithAbortSignal() {
|
||||
const ac = new AbortController();
|
||||
queueMicrotask(() => ac.abort());
|
||||
await assertRejects(async () => {
|
||||
await assertRejects(
|
||||
async () => {
|
||||
await Deno.readFile("cli/tests/testdata/fixture.json", {
|
||||
signal: ac.signal,
|
||||
});
|
||||
},
|
||||
(error: Error) => {
|
||||
assert(error instanceof DOMException);
|
||||
assertEquals(error.name, "AbortError");
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
Deno.test(
|
||||
{ permissions: { read: true } },
|
||||
async function readTextFileWithAbortSignalReason() {
|
||||
const ac = new AbortController();
|
||||
const abortReason = new Error();
|
||||
queueMicrotask(() => ac.abort(abortReason));
|
||||
await assertRejects(
|
||||
async () => {
|
||||
await Deno.readFile("cli/tests/testdata/fixture.json", {
|
||||
signal: ac.signal,
|
||||
});
|
||||
},
|
||||
(error: Error) => {
|
||||
assertEquals(error, abortReason);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
Deno.test(
|
||||
{ permissions: { read: true } },
|
||||
async function readTextFileWithAbortSignalPrimitiveReason() {
|
||||
const ac = new AbortController();
|
||||
queueMicrotask(() => ac.abort("Some string"));
|
||||
try {
|
||||
await Deno.readFile("cli/tests/testdata/fixture.json", {
|
||||
signal: ac.signal,
|
||||
});
|
||||
});
|
||||
unreachable();
|
||||
} catch (e) {
|
||||
assertEquals(e, "Some string");
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
assertEquals,
|
||||
assertRejects,
|
||||
assertThrows,
|
||||
unreachable,
|
||||
} from "./test_util.ts";
|
||||
|
||||
Deno.test(
|
||||
|
@ -250,6 +251,7 @@ Deno.test(
|
|||
queueMicrotask(() => ac.abort());
|
||||
try {
|
||||
await Deno.writeFile(filename, data, { signal: ac.signal });
|
||||
unreachable();
|
||||
} catch (e) {
|
||||
assert(e instanceof Error);
|
||||
assertEquals(e.name, "AbortError");
|
||||
|
@ -259,6 +261,45 @@ Deno.test(
|
|||
},
|
||||
);
|
||||
|
||||
Deno.test(
|
||||
{ permissions: { read: true, write: true } },
|
||||
async function writeFileAbortSignalReason(): Promise<void> {
|
||||
const ac = new AbortController();
|
||||
const enc = new TextEncoder();
|
||||
const data = enc.encode("Hello");
|
||||
const filename = Deno.makeTempDirSync() + "/test.txt";
|
||||
const abortReason = new Error();
|
||||
queueMicrotask(() => ac.abort(abortReason));
|
||||
try {
|
||||
await Deno.writeFile(filename, data, { signal: ac.signal });
|
||||
unreachable();
|
||||
} catch (e) {
|
||||
assertEquals(e, abortReason);
|
||||
}
|
||||
const stat = Deno.statSync(filename);
|
||||
assertEquals(stat.size, 0);
|
||||
},
|
||||
);
|
||||
|
||||
Deno.test(
|
||||
{ permissions: { read: true, write: true } },
|
||||
async function writeFileAbortSignalPrimitiveReason(): Promise<void> {
|
||||
const ac = new AbortController();
|
||||
const enc = new TextEncoder();
|
||||
const data = enc.encode("Hello");
|
||||
const filename = Deno.makeTempDirSync() + "/test.txt";
|
||||
queueMicrotask(() => ac.abort("Some string"));
|
||||
try {
|
||||
await Deno.writeFile(filename, data, { signal: ac.signal });
|
||||
unreachable();
|
||||
} catch (e) {
|
||||
assertEquals(e, "Some string");
|
||||
}
|
||||
const stat = Deno.statSync(filename);
|
||||
assertEquals(stat.size, 0);
|
||||
},
|
||||
);
|
||||
|
||||
Deno.test(
|
||||
{ permissions: { read: true, write: true } },
|
||||
async function writeFileAbortSignalPreAborted(): Promise<void> {
|
||||
|
@ -269,6 +310,7 @@ Deno.test(
|
|||
const filename = Deno.makeTempDirSync() + "/test.txt";
|
||||
try {
|
||||
await Deno.writeFile(filename, data, { signal: ac.signal });
|
||||
unreachable();
|
||||
} catch (e) {
|
||||
assert(e instanceof Error);
|
||||
assertEquals(e.name, "AbortError");
|
||||
|
@ -277,3 +319,44 @@ Deno.test(
|
|||
assertEquals(stat.size, 0);
|
||||
},
|
||||
);
|
||||
|
||||
Deno.test(
|
||||
{ permissions: { read: true, write: true } },
|
||||
async function writeFileAbortSignalReasonPreAborted(): Promise<void> {
|
||||
const ac = new AbortController();
|
||||
const abortReason = new Error();
|
||||
ac.abort(abortReason);
|
||||
const enc = new TextEncoder();
|
||||
const data = enc.encode("Hello");
|
||||
const filename = Deno.makeTempDirSync() + "/test.txt";
|
||||
try {
|
||||
await Deno.writeFile(filename, data, { signal: ac.signal });
|
||||
unreachable();
|
||||
} catch (e) {
|
||||
assertEquals(e, abortReason);
|
||||
}
|
||||
const stat = Deno.statSync(filename);
|
||||
assertEquals(stat.size, 0);
|
||||
},
|
||||
);
|
||||
|
||||
Deno.test(
|
||||
{ permissions: { read: true, write: true } },
|
||||
async function writeFileAbortSignalPrimitiveReasonPreAborted(): Promise<
|
||||
void
|
||||
> {
|
||||
const ac = new AbortController();
|
||||
ac.abort("Some string");
|
||||
const enc = new TextEncoder();
|
||||
const data = enc.encode("Hello");
|
||||
const filename = Deno.makeTempDirSync() + "/test.txt";
|
||||
try {
|
||||
await Deno.writeFile(filename, data, { signal: ac.signal });
|
||||
unreachable();
|
||||
} catch (e) {
|
||||
assertEquals(e, "Some string");
|
||||
}
|
||||
const stat = Deno.statSync(filename);
|
||||
assertEquals(stat.size, 0);
|
||||
},
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue