File
Blob: src/client/server/error.ts
| 1 | import { renderUiView } from "@/client/server/render"; |
| 2 | import { escapeHtml } from "@/shared/web/format"; |
| 3 | import { isHttpError } from "@/shared/web/http"; |
| 4 | |
| 5 | export async function handleError( |
| 6 | env: Env, |
| 7 | error: unknown, |
| 8 | fallbackTitle: string, |
| 9 | extra?: { |
| 10 | owner?: string; |
| 11 | repo?: string; |
| 12 | refEnc?: string; |
| 13 | path?: string; |
| 14 | } |
| 15 | ): Promise<Response> { |
| 16 | const debug = String(env.LOG_LEVEL || "").toLowerCase() === "debug"; |
| 17 | const httpError = isHttpError(error) ? error : undefined; |
| 18 | const status = |
| 19 | httpError?.status ?? (/not found/i.test(String((error as any)?.message)) ? 404 : 500); |
| 20 | |
| 21 | try { |
| 22 | const html = await renderUiView(env, "error", { |
| 23 | title: fallbackTitle, |
| 24 | message: String((error as any)?.message || error), |
| 25 | owner: extra?.owner, |
| 26 | repo: extra?.repo, |
| 27 | refEnc: extra?.refEnc, |
| 28 | path: extra?.path, |
| 29 | stack: debug ? String((error as any)?.stack || "") : undefined, |
| 30 | }); |
| 31 | if (html) { |
| 32 | return new Response(html, { |
| 33 | status, |
| 34 | headers: { "Content-Type": "text/html; charset=utf-8" }, |
| 35 | }); |
| 36 | } |
| 37 | } catch {} |
| 38 | |
| 39 | return new Response( |
| 40 | `<h2>Error</h2><pre>${escapeHtml(String((error as any)?.message || error))}</pre>`, |
| 41 | { |
| 42 | status, |
| 43 | headers: { "Content-Type": "text/html; charset=utf-8" }, |
| 44 | } |
| 45 | ); |
| 46 | } |