Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions application.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1105,10 +1105,8 @@ Deno.test({
});

Deno.test({
name: "Application.listen() - no options",
name: "Application.listen() - no options - aborted before onListen",
// ignore: isNode(),
ignore: true, // there is a challenge with serve and the abort controller that
// needs to be isolated
async fn() {
const controller = new AbortController();
const app = new Application();
Expand All @@ -1118,6 +1116,22 @@ Deno.test({
const { signal } = controller;
const p = app.listen({ signal });
controller.abort();
assertRejects(async () => await p, "aborted prematurely before 'listen' event");
teardown();
},
});

Deno.test({
name: "Application.listen() - no options - aborted after onListen",
async fn() {
const controller = new AbortController();
const app = new Application();
app.use((ctx) => {
ctx.response.body = "hello world";
});
const { signal } = controller;
app.addEventListener("listen", () => controller.abort())
const p = app.listen({ signal });
await p;
teardown();
},
Expand Down
7 changes: 7 additions & 0 deletions http_server_native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ export class Server<AS extends State = Record<string, any>>
const { signal } = this.#options;
const { onListen, ...options } = this.#options;
const { promise, resolve } = createPromiseWithResolvers<Listener>();
if (signal?.aborted) {
// if user somehow aborted before `listen` is invoked, we throw
return Promise.reject(new Error("aborted prematurely before 'listen' event"));
}
this.#stream = new ReadableStream<NativeRequest>({
start: (controller) => {
this.#httpServer = serve?.({
Expand All @@ -96,6 +100,9 @@ export class Server<AS extends State = Record<string, any>>
signal,
...options,
});
// closinng stream, so that the Application listen promise can resolve itself
// https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamDefaultController/close
signal?.addEventListener("abort", () => controller.close(), { once: true });
},
});

Expand Down