Skip to content

Commit

Permalink
refactor: error handling plugin (denoland#550)
Browse files Browse the repository at this point in the history
  • Loading branch information
iuioiua authored Sep 10, 2023
1 parent 7bfbf4b commit 44ea87d
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 86 deletions.
8 changes: 7 additions & 1 deletion fresh.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ import twindPlugin from "$fresh/plugins/twindv1.ts";
import twindConfig from "./twind.config.ts";
import kvOAuthPlugin from "./plugins/kv_oauth.ts";
import protectedRoutes from "./plugins/protected_routes.ts";
import errorHandling from "./plugins/error_handling.ts";
import { FreshOptions } from "$fresh/server.ts";

export default {
plugins: [kvOAuthPlugin, protectedRoutes, twindPlugin(twindConfig)],
plugins: [
kvOAuthPlugin,
protectedRoutes,
twindPlugin(twindConfig),
errorHandling,
],
} as FreshOptions;
98 changes: 48 additions & 50 deletions fresh.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,30 @@ import * as $3 from "./routes/_middleware.ts";
import * as $4 from "./routes/account/index.tsx";
import * as $5 from "./routes/account/manage.ts";
import * as $6 from "./routes/account/upgrade.ts";
import * as $7 from "./routes/api/_middleware.ts";
import * as $8 from "./routes/api/comments.ts";
import * as $9 from "./routes/api/items/[id]/comments.ts";
import * as $10 from "./routes/api/items/[id]/index.ts";
import * as $11 from "./routes/api/items/[id]/vote.ts";
import * as $12 from "./routes/api/items/index.ts";
import * as $13 from "./routes/api/me/notifications.ts";
import * as $14 from "./routes/api/me/votes.ts";
import * as $15 from "./routes/api/stripe-webhooks.ts";
import * as $16 from "./routes/api/users/[login]/index.ts";
import * as $17 from "./routes/api/users/[login]/items.ts";
import * as $18 from "./routes/api/users/index.ts";
import * as $19 from "./routes/blog/[slug].tsx";
import * as $20 from "./routes/blog/index.tsx";
import * as $21 from "./routes/dashboard/index.tsx";
import * as $22 from "./routes/dashboard/stats.tsx";
import * as $23 from "./routes/dashboard/users.tsx";
import * as $24 from "./routes/feed.ts";
import * as $25 from "./routes/index.tsx";
import * as $26 from "./routes/items/[id].tsx";
import * as $27 from "./routes/notifications/[id].ts";
import * as $28 from "./routes/notifications/index.tsx";
import * as $29 from "./routes/pricing.tsx";
import * as $30 from "./routes/submit.tsx";
import * as $31 from "./routes/users/[login].tsx";
import * as $7 from "./routes/api/comments.ts";
import * as $8 from "./routes/api/items/[id]/comments.ts";
import * as $9 from "./routes/api/items/[id]/index.ts";
import * as $10 from "./routes/api/items/[id]/vote.ts";
import * as $11 from "./routes/api/items/index.ts";
import * as $12 from "./routes/api/me/notifications.ts";
import * as $13 from "./routes/api/me/votes.ts";
import * as $14 from "./routes/api/stripe-webhooks.ts";
import * as $15 from "./routes/api/users/[login]/index.ts";
import * as $16 from "./routes/api/users/[login]/items.ts";
import * as $17 from "./routes/api/users/index.ts";
import * as $18 from "./routes/blog/[slug].tsx";
import * as $19 from "./routes/blog/index.tsx";
import * as $20 from "./routes/dashboard/index.tsx";
import * as $21 from "./routes/dashboard/stats.tsx";
import * as $22 from "./routes/dashboard/users.tsx";
import * as $23 from "./routes/feed.ts";
import * as $24 from "./routes/index.tsx";
import * as $25 from "./routes/items/[id].tsx";
import * as $26 from "./routes/notifications/[id].ts";
import * as $27 from "./routes/notifications/index.tsx";
import * as $28 from "./routes/pricing.tsx";
import * as $29 from "./routes/submit.tsx";
import * as $30 from "./routes/users/[login].tsx";
import * as $$0 from "./islands/Chart.tsx";
import * as $$1 from "./islands/CommentsList.tsx";
import * as $$2 from "./islands/ItemsList.tsx";
Expand All @@ -50,31 +49,30 @@ const manifest = {
"./routes/account/index.tsx": $4,
"./routes/account/manage.ts": $5,
"./routes/account/upgrade.ts": $6,
"./routes/api/_middleware.ts": $7,
"./routes/api/comments.ts": $8,
"./routes/api/items/[id]/comments.ts": $9,
"./routes/api/items/[id]/index.ts": $10,
"./routes/api/items/[id]/vote.ts": $11,
"./routes/api/items/index.ts": $12,
"./routes/api/me/notifications.ts": $13,
"./routes/api/me/votes.ts": $14,
"./routes/api/stripe-webhooks.ts": $15,
"./routes/api/users/[login]/index.ts": $16,
"./routes/api/users/[login]/items.ts": $17,
"./routes/api/users/index.ts": $18,
"./routes/blog/[slug].tsx": $19,
"./routes/blog/index.tsx": $20,
"./routes/dashboard/index.tsx": $21,
"./routes/dashboard/stats.tsx": $22,
"./routes/dashboard/users.tsx": $23,
"./routes/feed.ts": $24,
"./routes/index.tsx": $25,
"./routes/items/[id].tsx": $26,
"./routes/notifications/[id].ts": $27,
"./routes/notifications/index.tsx": $28,
"./routes/pricing.tsx": $29,
"./routes/submit.tsx": $30,
"./routes/users/[login].tsx": $31,
"./routes/api/comments.ts": $7,
"./routes/api/items/[id]/comments.ts": $8,
"./routes/api/items/[id]/index.ts": $9,
"./routes/api/items/[id]/vote.ts": $10,
"./routes/api/items/index.ts": $11,
"./routes/api/me/notifications.ts": $12,
"./routes/api/me/votes.ts": $13,
"./routes/api/stripe-webhooks.ts": $14,
"./routes/api/users/[login]/index.ts": $15,
"./routes/api/users/[login]/items.ts": $16,
"./routes/api/users/index.ts": $17,
"./routes/blog/[slug].tsx": $18,
"./routes/blog/index.tsx": $19,
"./routes/dashboard/index.tsx": $20,
"./routes/dashboard/stats.tsx": $21,
"./routes/dashboard/users.tsx": $22,
"./routes/feed.ts": $23,
"./routes/index.tsx": $24,
"./routes/items/[id].tsx": $25,
"./routes/notifications/[id].ts": $26,
"./routes/notifications/index.tsx": $27,
"./routes/pricing.tsx": $28,
"./routes/submit.tsx": $29,
"./routes/users/[login].tsx": $30,
},
islands: {
"./islands/Chart.tsx": $$0,
Expand Down
66 changes: 37 additions & 29 deletions middleware/errors.ts → plugins/error_handling.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
// Copyright 2023 the Deno authors. All rights reserved. MIT license.
import { type MiddlewareHandlerContext, Status } from "$fresh/server.ts";
import { redirect } from "@/utils/http.ts";
import type { Plugin } from "$fresh/server.ts";
import type { State } from "@/middleware/session.ts";
import { Status } from "$fresh/server.ts";
import { errors, isHttpError } from "std/http/http_errors.ts";

// For web pages
export async function handleWebPageErrors(
_req: Request,
ctx: MiddlewareHandlerContext,
) {
try {
return await ctx.next();
} catch (error) {
if (error instanceof errors.Unauthorized) return redirect("/signin");
throw error;
}
}
import { redirect } from "@/utils/http.ts";

/**
* Returns the converted HTTP error response from the given error. If the error
Expand All @@ -32,7 +21,7 @@ export async function handleWebPageErrors(
*
* @example
* ```ts
* import { toErrorResponse } from "@/middleware/errors.ts";
* import { toErrorResponse } from "@/plugins/error_handling.ts";
* import { errors } from "std/http/http_errors.ts";
*
* const resp = toErrorResponse(new errors.NotFound("User not found"));
Expand All @@ -53,16 +42,35 @@ export function toErrorResponse(error: any) {
: new Response(error.message, { status: Status.InternalServerError });
}

/**
* Handles HTTP-flavored errors, if they are thrown in a proceeding middleware.
*/
export async function handleRestApiErrors(
_req: Request,
ctx: MiddlewareHandlerContext,
) {
try {
return await ctx.next();
} catch (error) {
return toErrorResponse(error);
}
}
export default {
name: "error-handling",
middlewares: [
{
path: "/",
middleware: {
async handler(_req, ctx) {
try {
return await ctx.next();
} catch (error) {
if (error instanceof errors.Unauthorized) {
return redirect("/signin");
}
throw error;
}
},
},
},
{
path: "/api",
middleware: {
async handler(_req, ctx) {
try {
return await ctx.next();
} catch (error) {
return toErrorResponse(error);
}
},
},
},
],
} as Plugin<State>;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright 2023 the Deno authors. All rights reserved. MIT license.
import { createHttpError } from "std/http/http_errors.ts";
import { toErrorResponse } from "./errors.ts";
import { toErrorResponse } from "./error_handling.ts";
import { Status } from "std/http/http_status.ts";
import { assertEquals } from "std/assert/assert_equals.ts";
import { assertFalse } from "std/assert/assert_false.ts";
Expand Down
4 changes: 1 addition & 3 deletions routes/_middleware.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// Copyright 2023 the Deno authors. All rights reserved. MIT license.
import { MiddlewareHandlerContext } from "$fresh/server.ts";
import type { MiddlewareHandlerContext } from "$fresh/server.ts";
import { redirect } from "@/utils/http.ts";
import { Status } from "std/http/http_status.ts";
import { incrVisitsCountByDay } from "@/utils/db.ts";
import { setSessionState } from "@/middleware/session.ts";
import { handleWebPageErrors } from "@/middleware/errors.ts";

async function redirectToNewOrigin(
req: Request,
Expand All @@ -29,6 +28,5 @@ async function recordVisit(
export const handler = [
redirectToNewOrigin,
setSessionState,
handleWebPageErrors,
recordVisit,
];
2 changes: 0 additions & 2 deletions routes/api/_middleware.ts

This file was deleted.

0 comments on commit 44ea87d

Please sign in to comment.