Skip to content
This repository was archived by the owner on Jul 6, 2025. It is now read-only.

Commit bd3c084

Browse files
committed
Update onError callback arguments
1 parent e4e5f23 commit bd3c084

File tree

2 files changed

+41
-33
lines changed

2 files changed

+41
-33
lines changed

server/mod.ts

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { serve as stdServe, type ServeInit, serveTls } from "https://deno.land/[email protected]/http/server.ts";
1+
import type { ConnInfo, ServeInit } from "https://deno.land/[email protected]/http/server.ts";
2+
import { serve as stdServe, serveTls } from "https://deno.land/[email protected]/http/server.ts";
23
import { readableStreamFromReader } from "https://deno.land/[email protected]/streams/conversion.ts";
34
import { VERSION } from "https://deno.land/x/[email protected]/version.ts";
45
import FetchError from "../framework/core/fetch_error.ts";
@@ -26,8 +27,10 @@ export type ServerOptions = Omit<ServeInit, "onError"> & {
2627
ssr?: SSR;
2728
onError?: (
2829
error: unknown,
29-
cause: "api" | "ssr" | "transplie" | "fs" | "middleware",
30-
url: string,
30+
cause: {
31+
by: "data-fetching" | "ssr" | "transplie" | "fs" | "middleware";
32+
url: string;
33+
},
3134
) => Response | void;
3235
};
3336

@@ -48,7 +51,7 @@ export const serve = (options: ServerOptions = {}) => {
4851
});
4952
return util.computeHash("sha-1", buildArgs);
5053
});
51-
const handler = async (req: Request): Promise<Response> => {
54+
const handler = async (req: Request, connInfo: ConnInfo): Promise<Response> => {
5255
const url = new URL(req.url);
5356
const { host, pathname } = url;
5457

@@ -78,7 +81,7 @@ export const serve = (options: ServerOptions = {}) => {
7881
} catch (err) {
7982
if (!(err instanceof Deno.errors.NotFound)) {
8083
log.error(err);
81-
return onError?.(err, "transplie", req.url) ??
84+
return onError?.(err, { by: "transplie", url: req.url }) ??
8285
new Response(errorHtml(err.stack ?? err.message), {
8386
status: 500,
8487
headers: [["Content-Type", "text/html"]],
@@ -109,7 +112,7 @@ export const serve = (options: ServerOptions = {}) => {
109112
} catch (err) {
110113
if (!(err instanceof Deno.errors.NotFound)) {
111114
log.error(err);
112-
return onError?.(err, "transplie", req.url) ??
115+
return onError?.(err, { by: "transplie", url: req.url }) ??
113116
new Response(errorHtml(err.stack ?? err.message), {
114117
status: 500,
115118
headers: [["Content-Type", "text/html"]],
@@ -153,7 +156,7 @@ export const serve = (options: ServerOptions = {}) => {
153156
} catch (err) {
154157
if (!(err instanceof Deno.errors.NotFound)) {
155158
log.error(err);
156-
return onError?.(err, "fs", req.url) ??
159+
return onError?.(err, { by: "fs", url: req.url }) ??
157160
new Response(errorHtml(err.stack ?? err.message), {
158161
status: 500,
159162
headers: [["Content-Type", "text/html"]],
@@ -175,6 +178,7 @@ export const serve = (options: ServerOptions = {}) => {
175178

176179
const customHTMLRewriter = new Map<string, HTMLRewriterHandlers>();
177180
const ctx = {
181+
connInfo,
178182
params: {},
179183
headers: new Headers(),
180184
cookies: {
@@ -239,8 +243,8 @@ export const serve = (options: ServerOptions = {}) => {
239243

240244
// use middlewares
241245
if (Array.isArray(middlewares) && middlewares.length > 0) {
242-
try {
243-
for (const mw of middlewares) {
246+
for (const mw of middlewares) {
247+
try {
244248
const handler = mw.fetch;
245249
if (typeof handler === "function") {
246250
let res = handler(req, ctx);
@@ -254,10 +258,13 @@ export const serve = (options: ServerOptions = {}) => {
254258
setTimeout(res, 0);
255259
}
256260
}
261+
} catch (err) {
262+
return onError?.(err, { by: "middleware", url: req.url }) ??
263+
new Response(errorHtml(err.stack ?? err.message), {
264+
status: 500,
265+
headers: [["Content-Type", "text/html"]],
266+
});
257267
}
258-
} catch (err) {
259-
return onError?.(err, "middleware", req.url) ??
260-
new Response(errorHtml(err.stack ?? err.message), { status: 500, headers: [["Content-Type", "text/html"]] });
261268
}
262269
}
263270

@@ -296,7 +303,7 @@ export const serve = (options: ServerOptions = {}) => {
296303
) {
297304
return new Response(res);
298305
}
299-
if (res instanceof Blob) {
306+
if (res instanceof Blob || res instanceof File) {
300307
return new Response(res, { headers: { "Content-Type": res.type } });
301308
}
302309
if (util.isPlainObject(res) || Array.isArray(res) || res === null) {
@@ -306,26 +313,25 @@ export const serve = (options: ServerOptions = {}) => {
306313
}
307314
return new Response("Method not allowed", { status: 405 });
308315
}
309-
} catch (error) {
310-
let err = error;
311-
if (err instanceof Response) {
312-
if (err.ok || !fromFetchApi) {
313-
return err;
314-
}
315-
err = await FetchError.fromResponse(err);
316-
}
317-
const res = onError?.(err, "api", req.url);
316+
} catch (err) {
317+
const res = onError?.(err, { by: "data-fetching", url: req.url });
318318
if (res instanceof Response) {
319-
if (!fromFetchApi) {
320-
return err;
321-
}
322-
err = await FetchError.fromResponse(res);
319+
return res;
323320
}
324-
if (err instanceof Error) {
321+
if (err instanceof Response) {
322+
return err;
323+
}
324+
if (err instanceof Error || typeof err === "string") {
325325
log.error(err);
326326
}
327327
const status: number = util.isUint(err.status || err.code) ? err.status || err.code : 500;
328-
return ctx.json({ ...err, message: err.message, status }, { status: status >= 400 ? status : 501 });
328+
return ctx.json({
329+
...err,
330+
message: err.message || String(err),
331+
status,
332+
}, {
333+
status: status >= 400 ? status : 501,
334+
});
329335
}
330336
}
331337
}
@@ -353,7 +359,7 @@ export const serve = (options: ServerOptions = {}) => {
353359
indexHtml = null;
354360
} else {
355361
log.error("read index.html:", err);
356-
return onError?.(err, "fs", req.url) ??
362+
return onError?.(err, { by: "fs", url: req.url }) ??
357363
new Response(errorHtml(err.stack ?? err.message), {
358364
status: 500,
359365
headers: [["Content-Type", "text/html"]],

server/renderer.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export type RenderOptions = {
4444
customHTMLRewriter: Map<string, HTMLRewriterHandlers>;
4545
isDev: boolean;
4646
ssr?: SSR;
47-
onError?: (error: unknown, cause: "ssr", url: string) => Response | void;
47+
onError?: (error: unknown, cause: { by: "ssr"; url: string }) => Response | void;
4848
};
4949

5050
/** The virtual `bootstrapScript` to mark the ssr streaming initial UI is ready */
@@ -331,7 +331,7 @@ async function initSSR(
331331
ctx: Record<string, unknown>,
332332
routes: Routes,
333333
suspense: boolean,
334-
onError?: (error: unknown, cause: "ssr", url: string) => Response | void,
334+
onError?: (error: unknown, cause: { by: "ssr"; url: string }) => Response | void,
335335
): Promise<
336336
[
337337
url: URL,
@@ -379,7 +379,7 @@ async function initSSR(
379379
res = await res;
380380
}
381381
} catch (error) {
382-
if (!(res = onError?.(error, "ssr", req.url))) {
382+
if (!(res = onError?.(error, { by: "ssr", url: req.url }))) {
383383
throw error;
384384
}
385385
}
@@ -389,7 +389,7 @@ async function initSSR(
389389
}
390390
if (res.status >= 300) {
391391
if (res.headers.has("Location")) {
392-
throw Response.redirect(res.headers.get("Location")!, res.status);
392+
throw res;
393393
}
394394
throw new FetchError(500, {}, "Missing the `Location` header");
395395
}
@@ -402,6 +402,8 @@ async function initSSR(
402402
} catch (_e) {
403403
throw new FetchError(500, {}, "Data must be valid JSON");
404404
}
405+
} else if (util.isPlainObject(res) || Array.isArray(res)) {
406+
return res;
405407
} else {
406408
throw new FetchError(500, {}, "No response from data fetcher");
407409
}

0 commit comments

Comments
 (0)