Skip to content

Commit e2e8a42

Browse files
committed
fix: wrap promise on server runtime
1 parent 413cd4b commit e2e8a42

File tree

7 files changed

+49
-16
lines changed

7 files changed

+49
-16
lines changed

src/_plugin.ts

-4
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,6 @@ export function wrapFetch(server: Server, fetchHandler: ServerHandler) {
6666
}
6767
}
6868

69-
if (resPromise && server.options.onError) {
70-
resPromise = resPromise.catch(server.options.onError);
71-
}
72-
7369
// Response hooks
7470
if (hasResponseHooks) {
7571
for (const resHook of responseHooks) {

src/_utils.ts

+19-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ServerOptions } from "./types";
1+
import type { ErrorHandler, ServerHandler, ServerOptions } from "./types";
22

33
import { readFileSync } from "node:fs";
44

@@ -67,3 +67,21 @@ function resolveCertOrKey(value?: unknown): undefined | string {
6767
}
6868
return readFileSync(value, "utf8");
6969
}
70+
71+
export function wrapFetchOnError(
72+
fetchHandler: ServerHandler,
73+
onError?: ErrorHandler,
74+
): ServerHandler {
75+
if (!onError) return fetchHandler;
76+
return (...params) => {
77+
try {
78+
const result = fetchHandler(...params);
79+
if (result instanceof Promise) {
80+
return result.catch(onError);
81+
}
82+
return result;
83+
} catch (error) {
84+
return onError(error as Error);
85+
}
86+
};
87+
}

src/adapters/bun.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { BunFetchHandler, Server, ServerOptions } from "../types.ts";
22
import type * as bun from "bun";
3-
import { resolvePort, resolveTLSOptions } from "../_utils.ts";
3+
import { resolvePort, resolveTLSOptions, wrapFetchOnError } from "../_utils.ts";
44
import { wrapFetch } from "../_plugin.ts";
55

66
export const Response = globalThis.Response;
@@ -21,7 +21,9 @@ class BunServer implements Server<BunFetchHandler> {
2121
constructor(options: ServerOptions) {
2222
this.options = options;
2323

24-
const fetchHandler = wrapFetch(this, this.options.fetch);
24+
let fetchHandler = this.options.fetch;
25+
fetchHandler = wrapFetchOnError(this.options.fetch, this.options.onError);
26+
fetchHandler = wrapFetch(this as unknown as Server, fetchHandler);
2527

2628
this.fetch = (request, server) => {
2729
Object.defineProperties(request, {

src/adapters/cloudflare.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
} from "../types.ts";
66
import type * as CF from "@cloudflare/workers-types";
77
import { wrapFetch } from "../_plugin.ts";
8+
import { wrapFetchOnError } from "../_utils.ts";
89

910
export const Response = globalThis.Response;
1011

@@ -23,10 +24,9 @@ class CloudflareServer implements Server<CloudflareFetchHandler> {
2324
constructor(options: ServerOptions) {
2425
this.options = options;
2526

26-
const fetchHandler = wrapFetch(
27-
this as unknown as Server,
28-
this.options.fetch,
29-
);
27+
let fetchHandler = this.options.fetch;
28+
fetchHandler = wrapFetchOnError(this.options.fetch, this.options.onError);
29+
fetchHandler = wrapFetch(this as unknown as Server, fetchHandler);
3030

3131
this.fetch = (request, env, context) => {
3232
Object.defineProperties(request, {

src/adapters/deno.ts

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import type { DenoFetchHandler, Server, ServerOptions } from "../types.ts";
2-
import { fmtURL, resolvePort, resolveTLSOptions } from "../_utils.ts";
2+
import {
3+
fmtURL,
4+
resolvePort,
5+
resolveTLSOptions,
6+
wrapFetchOnError,
7+
} from "../_utils.ts";
38
import { wrapFetch } from "../_plugin.ts";
49

510
export const Response = globalThis.Response;
@@ -25,7 +30,9 @@ class DenoServer implements Server<DenoFetchHandler> {
2530
constructor(options: ServerOptions) {
2631
this.options = options;
2732

28-
const fetchHandler = wrapFetch(this, this.options.fetch);
33+
let fetchHandler = this.options.fetch;
34+
fetchHandler = wrapFetchOnError(this.options.fetch, this.options.onError);
35+
fetchHandler = wrapFetch(this, fetchHandler);
2936

3037
this.fetch = (request, info) => {
3138
Object.defineProperties(request, {

src/adapters/node.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ import NodeHttp from "node:http";
99
import NodeHttps from "node:https";
1010
import { sendNodeResponse } from "../_node-compat/send.ts";
1111
import { NodeRequest } from "../_node-compat/request.ts";
12-
import { fmtURL, resolvePort, resolveTLSOptions } from "../_utils.ts";
12+
import {
13+
fmtURL,
14+
resolvePort,
15+
resolveTLSOptions,
16+
wrapFetchOnError,
17+
} from "../_utils.ts";
1318
import { wrapFetch } from "../_plugin.ts";
1419

1520
export {
@@ -53,7 +58,10 @@ class NodeServer implements Server {
5358
constructor(options: ServerOptions) {
5459
this.options = options;
5560

56-
const fetchHandler = wrapFetch(this, this.options.fetch);
61+
let fetchHandler = this.options.fetch;
62+
fetchHandler = wrapFetchOnError(this.options.fetch, this.options.onError);
63+
fetchHandler = wrapFetch(this, fetchHandler);
64+
5765
this.fetch = fetchHandler;
5866

5967
const handler = (

src/types.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export interface ServerOptions {
100100
*
101101
* @note This handler will take precedence over runtime specific error handlers.
102102
*/
103-
onError?: (error: Error) => MaybePromise<Response>;
103+
onError?: ErrorHandler;
104104

105105
/**
106106
* Node.js server options.
@@ -256,6 +256,8 @@ export interface ServerRequest extends Request {
256256

257257
export type FetchHandler = (request: Request) => Response | Promise<Response>;
258258

259+
export type ErrorHandler = (error: Error) => Response | Promise<Response>;
260+
259261
export type BunFetchHandler = (
260262
request: Request,
261263
server?: Bun.Server,

0 commit comments

Comments
 (0)