Skip to content

Commit 9ad0d4c

Browse files
authored
fix(ext/http): improve error message when underlying resource of request body unavailable (#27463)
The error message is currently `Bad Resource ID`. This commit changes it to `Cannot read request body as underlying resource unavailable` closes #27133
1 parent 7cabd02 commit 9ad0d4c

File tree

3 files changed

+69
-4
lines changed

3 files changed

+69
-4
lines changed

ext/http/00_serve.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,25 @@ class InnerRequest {
370370
return null;
371371
}
372372
this.#streamRid = op_http_read_request_body(this.#external);
373-
this.#body = new InnerBody(readableStreamForRid(this.#streamRid, false));
373+
this.#body = new InnerBody(
374+
readableStreamForRid(
375+
this.#streamRid,
376+
false,
377+
undefined,
378+
(controller, error) => {
379+
if (ObjectPrototypeIsPrototypeOf(BadResourcePrototype, error)) {
380+
// TODO(kt3k): We would like to pass `error` as `cause` when BadResource supports it.
381+
controller.error(
382+
new error.constructor(
383+
`Cannot read request body as underlying resource unavailable`,
384+
),
385+
);
386+
} else {
387+
controller.error(error);
388+
}
389+
},
390+
),
391+
);
374392
return this.#body;
375393
}
376394

ext/web/06_streams.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -908,7 +908,7 @@ const _original = Symbol("[[original]]");
908908
* @param {boolean=} autoClose If the resource should be auto-closed when the stream closes. Defaults to true.
909909
* @returns {ReadableStream<Uint8Array>}
910910
*/
911-
function readableStreamForRid(rid, autoClose = true, Super) {
911+
function readableStreamForRid(rid, autoClose = true, Super, onError) {
912912
const stream = new (Super ?? ReadableStream)(_brand);
913913
stream[_resourceBacking] = { rid, autoClose };
914914

@@ -947,7 +947,11 @@ function readableStreamForRid(rid, autoClose = true, Super) {
947947
controller.byobRequest.respond(bytesRead);
948948
}
949949
} catch (e) {
950-
controller.error(e);
950+
if (onError) {
951+
onError(controller, e);
952+
} else {
953+
controller.error(e);
954+
}
951955
tryClose();
952956
}
953957
},

tests/unit/serve_test.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
// deno-lint-ignore-file no-console
44

5-
import { assertMatch, assertRejects } from "@std/assert";
5+
import { assertIsError, assertMatch, assertRejects } from "@std/assert";
66
import { Buffer, BufReader, BufWriter, type Reader } from "@std/io";
77
import { TextProtoReader } from "../testdata/run/textproto.ts";
88
import {
@@ -4378,3 +4378,46 @@ Deno.test(
43784378
await server.finished;
43794379
},
43804380
);
4381+
4382+
Deno.test({
4383+
name:
4384+
"req.body.getReader().read() throws the error with reasonable error message",
4385+
}, async () => {
4386+
const { promise, resolve, reject } = Promise.withResolvers<Error>();
4387+
const server = Deno.serve({ onListen, port: 0 }, async (req) => {
4388+
const reader = req.body!.getReader();
4389+
4390+
try {
4391+
while (true) {
4392+
const { done } = await reader.read();
4393+
if (done) break;
4394+
}
4395+
} catch (e) {
4396+
// deno-lint-ignore no-explicit-any
4397+
resolve(e as any);
4398+
}
4399+
4400+
reject(new Error("Should not reach here"));
4401+
server.shutdown();
4402+
return new Response();
4403+
});
4404+
4405+
async function onListen({ port }: { port: number }) {
4406+
const body = "a".repeat(1000);
4407+
const request = `POST / HTTP/1.1\r\n` +
4408+
`Host: 127.0.0.1:${port}\r\n` +
4409+
`Content-Length: 1000\r\n` +
4410+
"\r\n" + body;
4411+
4412+
const connection = await Deno.connect({ hostname: "127.0.0.1", port });
4413+
await connection.write(new TextEncoder().encode(request));
4414+
connection.close();
4415+
}
4416+
await server.finished;
4417+
const e = await promise;
4418+
assertIsError(
4419+
e,
4420+
Deno.errors.BadResource,
4421+
"Cannot read request body as underlying resource unavailable",
4422+
);
4423+
});

0 commit comments

Comments
 (0)