mirror of
https://github.com/denoland/deno.git
synced 2025-01-21 13:00:36 -05:00
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
This commit is contained in:
parent
7cabd02c59
commit
9ad0d4c3db
3 changed files with 69 additions and 4 deletions
|
@ -370,7 +370,25 @@ class InnerRequest {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
this.#streamRid = op_http_read_request_body(this.#external);
|
this.#streamRid = op_http_read_request_body(this.#external);
|
||||||
this.#body = new InnerBody(readableStreamForRid(this.#streamRid, false));
|
this.#body = new InnerBody(
|
||||||
|
readableStreamForRid(
|
||||||
|
this.#streamRid,
|
||||||
|
false,
|
||||||
|
undefined,
|
||||||
|
(controller, error) => {
|
||||||
|
if (ObjectPrototypeIsPrototypeOf(BadResourcePrototype, error)) {
|
||||||
|
// TODO(kt3k): We would like to pass `error` as `cause` when BadResource supports it.
|
||||||
|
controller.error(
|
||||||
|
new error.constructor(
|
||||||
|
`Cannot read request body as underlying resource unavailable`,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
controller.error(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
return this.#body;
|
return this.#body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -908,7 +908,7 @@ const _original = Symbol("[[original]]");
|
||||||
* @param {boolean=} autoClose If the resource should be auto-closed when the stream closes. Defaults to true.
|
* @param {boolean=} autoClose If the resource should be auto-closed when the stream closes. Defaults to true.
|
||||||
* @returns {ReadableStream<Uint8Array>}
|
* @returns {ReadableStream<Uint8Array>}
|
||||||
*/
|
*/
|
||||||
function readableStreamForRid(rid, autoClose = true, Super) {
|
function readableStreamForRid(rid, autoClose = true, Super, onError) {
|
||||||
const stream = new (Super ?? ReadableStream)(_brand);
|
const stream = new (Super ?? ReadableStream)(_brand);
|
||||||
stream[_resourceBacking] = { rid, autoClose };
|
stream[_resourceBacking] = { rid, autoClose };
|
||||||
|
|
||||||
|
@ -947,7 +947,11 @@ function readableStreamForRid(rid, autoClose = true, Super) {
|
||||||
controller.byobRequest.respond(bytesRead);
|
controller.byobRequest.respond(bytesRead);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
controller.error(e);
|
if (onError) {
|
||||||
|
onError(controller, e);
|
||||||
|
} else {
|
||||||
|
controller.error(e);
|
||||||
|
}
|
||||||
tryClose();
|
tryClose();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
// deno-lint-ignore-file no-console
|
// deno-lint-ignore-file no-console
|
||||||
|
|
||||||
import { assertMatch, assertRejects } from "@std/assert";
|
import { assertIsError, assertMatch, assertRejects } from "@std/assert";
|
||||||
import { Buffer, BufReader, BufWriter, type Reader } from "@std/io";
|
import { Buffer, BufReader, BufWriter, type Reader } from "@std/io";
|
||||||
import { TextProtoReader } from "../testdata/run/textproto.ts";
|
import { TextProtoReader } from "../testdata/run/textproto.ts";
|
||||||
import {
|
import {
|
||||||
|
@ -4378,3 +4378,46 @@ Deno.test(
|
||||||
await server.finished;
|
await server.finished;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Deno.test({
|
||||||
|
name:
|
||||||
|
"req.body.getReader().read() throws the error with reasonable error message",
|
||||||
|
}, async () => {
|
||||||
|
const { promise, resolve, reject } = Promise.withResolvers<Error>();
|
||||||
|
const server = Deno.serve({ onListen, port: 0 }, async (req) => {
|
||||||
|
const reader = req.body!.getReader();
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
const { done } = await reader.read();
|
||||||
|
if (done) break;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// deno-lint-ignore no-explicit-any
|
||||||
|
resolve(e as any);
|
||||||
|
}
|
||||||
|
|
||||||
|
reject(new Error("Should not reach here"));
|
||||||
|
server.shutdown();
|
||||||
|
return new Response();
|
||||||
|
});
|
||||||
|
|
||||||
|
async function onListen({ port }: { port: number }) {
|
||||||
|
const body = "a".repeat(1000);
|
||||||
|
const request = `POST / HTTP/1.1\r\n` +
|
||||||
|
`Host: 127.0.0.1:${port}\r\n` +
|
||||||
|
`Content-Length: 1000\r\n` +
|
||||||
|
"\r\n" + body;
|
||||||
|
|
||||||
|
const connection = await Deno.connect({ hostname: "127.0.0.1", port });
|
||||||
|
await connection.write(new TextEncoder().encode(request));
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
await server.finished;
|
||||||
|
const e = await promise;
|
||||||
|
assertIsError(
|
||||||
|
e,
|
||||||
|
Deno.errors.BadResource,
|
||||||
|
"Cannot read request body as underlying resource unavailable",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue