diff --git a/ext/http/00_serve.ts b/ext/http/00_serve.ts index 87798656f1db84..6d23685d8ee61a 100644 --- a/ext/http/00_serve.ts +++ b/ext/http/00_serve.ts @@ -511,9 +511,15 @@ function mapToCallback(context, callback, onError) { ); } + if (response.type === "error") { + throw new TypeError( + "Return value from serve handler must not be an error response (like Response.error())", + ); + } + if (response.bodyUsed) { throw new TypeError( - "The body of the Response returned from the serve handler has already been consumed.", + "The body of the Response returned from the serve handler has already been consumed", ); } } catch (error) { diff --git a/tests/unit/serve_test.ts b/tests/unit/serve_test.ts index c1e217a110dc9d..d417d8d268f80a 100644 --- a/tests/unit/serve_test.ts +++ b/tests/unit/serve_test.ts @@ -678,6 +678,40 @@ Deno.test( }, ); +Deno.test( + { permissions: { net: true } }, + async function httpServerReturnErrorResponse() { + const ac = new AbortController(); + const { promise, resolve } = Promise.withResolvers(); + let hadError = false; + const server = Deno.serve({ + handler: () => { + return Response.error(); + }, + port: servePort, + signal: ac.signal, + onListen: onListen(resolve), + onError: () => { + hadError = true; + return new Response("Internal Server Error", { status: 500 }); + }, + }); + + await promise; + + const resp = await fetch(`http://127.0.0.1:${servePort}/`, { + headers: { "connection": "close" }, + }); + assertEquals(resp.status, 500); + const text = await resp.text(); + assertEquals(text, "Internal Server Error"); + assert(hadError); + + ac.abort(); + await server.finished; + }, +); + Deno.test({ permissions: { net: true } }, async function httpServerOverload1() { const ac = new AbortController(); const deferred = Promise.withResolvers();