diff options
author | Luca Casonato <hello@lcas.dev> | 2022-12-19 12:49:00 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-19 12:49:00 +0100 |
commit | 43b6390629ad62edbeca3b884ccee53422876a1a (patch) | |
tree | e72fb0808b5abb636e29c41c5fa5a7ee2a547435 /cli/tests/unit/fetch_test.ts | |
parent | 84b70dd2fb780a779930342d21c27e4e368070f1 (diff) |
fix(ext/fetch): handle errors in req body stream (#17081)
Right now an error in a request body stream causes an uncatchable
global promise rejection. This PR fixes this to instead propagate the
error correctly into the promise returned from `fetch`.
It additionally fixes errored readable stream bodies being treated as
successfully completed bodies by Rust.
Diffstat (limited to 'cli/tests/unit/fetch_test.ts')
-rw-r--r-- | cli/tests/unit/fetch_test.ts | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/cli/tests/unit/fetch_test.ts b/cli/tests/unit/fetch_test.ts index fde119bf1..7035fe444 100644 --- a/cli/tests/unit/fetch_test.ts +++ b/cli/tests/unit/fetch_test.ts @@ -4,6 +4,7 @@ import { assertEquals, assertRejects, deferred, + delay, fail, unimplemented, } from "./test_util.ts"; @@ -1828,3 +1829,46 @@ Deno.test( assertEquals(req2.headers.get("x-foo"), "bar"); }, ); + +Deno.test( + { permissions: { net: true } }, + async function fetchRequestBodyErrorCatchable() { + const listener = Deno.listen({ hostname: "127.0.0.1", port: 4514 }); + const server = (async () => { + const conn = await listener.accept(); + listener.close(); + const buf = new Uint8Array(160); + const n = await conn.read(buf); + assertEquals(n, 160); // this is the request headers + first body chunk + const n2 = await conn.read(buf); + assertEquals(n2, 6); // this is the second body chunk + const n3 = await conn.read(buf); + assertEquals(n3, null); // the connection now abruptly closes because the client has errored + conn.close(); + })(); + + const stream = new ReadableStream({ + async start(controller) { + controller.enqueue(new TextEncoder().encode("a")); + await delay(1000); + controller.enqueue(new TextEncoder().encode("b")); + await delay(1000); + controller.error(new Error("foo")); + }, + }); + + const err = await assertRejects(() => + fetch("http://localhost:4514", { + body: stream, + method: "POST", + }) + ); + + assert(err instanceof TypeError); + assert(err.cause); + assert(err.cause instanceof Error); + assertEquals(err.cause.message, "foo"); + + await server; + }, +); |