Skip to content

Commit 63cb208

Browse files
fix(core): support method handler on _error, _404 and _500 routes (#2955)
This PR adds support for using method handlers in `_error`, `_404` and `_500` files. Fixes #2953
1 parent b852fe7 commit 63cb208

File tree

2 files changed

+82
-2
lines changed

2 files changed

+82
-2
lines changed

src/plugins/fs_routes/mod.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,16 @@ export async function fsRoutes<State>(
258258
? undefined
259259
: typeof handlers === "function"
260260
? handlers
261-
: undefined; // FIXME: Method handler
261+
: ((ctx) => {
262+
const { method } = ctx.req;
263+
if (!Array.isArray(handlers)) {
264+
const maybeFn = handlers[method as Method];
265+
if (maybeFn !== undefined) {
266+
return maybeFn(ctx);
267+
}
268+
}
269+
return ctx.next();
270+
}) as HandlerFn<unknown, State>;
262271
const errorComponents = components.slice();
263272
if (mod.component !== null) {
264273
errorComponents.push(mod.component);
@@ -285,7 +294,16 @@ export async function fsRoutes<State>(
285294
? undefined
286295
: typeof handlers === "function"
287296
? handlers
288-
: undefined; // FIXME: Method handler
297+
: ((ctx) => {
298+
const { method } = ctx.req;
299+
if (!Array.isArray(handlers)) {
300+
const maybeFn = handlers[method as Method];
301+
if (maybeFn !== undefined) {
302+
return maybeFn(ctx);
303+
}
304+
}
305+
return ctx.next();
306+
}) as HandlerFn<unknown, State>;
289307
const notFoundComponents = components.slice();
290308
if (mod.component !== null) {
291309
notFoundComponents.push(mod.component);

src/plugins/fs_routes/mod_test.tsx

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,28 @@ Deno.test("fsRoutes - _404", async () => {
646646
expect(content).toContain("Custom 404 - Not Found");
647647
});
648648

649+
Deno.test("fsRoutes - _404 method handler", async () => {
650+
const server = await createServer({
651+
"routes/_404.tsx": {
652+
handlers: {
653+
GET() {
654+
return new Response("ok");
655+
},
656+
},
657+
},
658+
"routes/index.tsx": {
659+
handlers: {
660+
GET() {
661+
return new Response("fail");
662+
},
663+
},
664+
},
665+
});
666+
667+
const res = await server.get("/invalid");
668+
expect(await res.text()).toEqual("ok");
669+
});
670+
649671
Deno.test("fsRoutes - _500", async () => {
650672
const server = await createServer({
651673
"routes/_500.tsx": {
@@ -665,6 +687,26 @@ Deno.test("fsRoutes - _500", async () => {
665687
expect(content).toContain("Custom Error Page");
666688
});
667689

690+
Deno.test("fsRoutes - _500 method handler", async () => {
691+
const server = await createServer({
692+
"routes/_500.tsx": {
693+
handlers: {
694+
GET() {
695+
return new Response("ok");
696+
},
697+
},
698+
},
699+
"routes/index.tsx": {
700+
handlers: () => {
701+
throw new Error("fail");
702+
},
703+
},
704+
});
705+
706+
const res = await server.get("/");
707+
expect(await res.text()).toEqual("ok");
708+
});
709+
668710
Deno.test("fsRoutes - _error", async () => {
669711
const server = await createServer({
670712
"routes/_error.tsx": {
@@ -730,6 +772,26 @@ Deno.test("fsRoutes - _error nested throw", async () => {
730772
expect(await res.text()).toEqual("ok");
731773
});
732774

775+
Deno.test("fsRoutes - _error method handler", async () => {
776+
const server = await createServer({
777+
"routes/_error.tsx": {
778+
handlers: {
779+
GET() {
780+
return new Response("ok");
781+
},
782+
},
783+
},
784+
"routes/index.tsx": {
785+
handlers: () => {
786+
throw new Error("fail");
787+
},
788+
},
789+
});
790+
791+
const res = await server.get("/");
792+
expect(await res.text()).toEqual("ok");
793+
});
794+
733795
Deno.test("fsRoutes - _error render component", async () => {
734796
const server = await createServer({
735797
"routes/_error.tsx": {

0 commit comments

Comments
 (0)