Skip to content

Commit

Permalink
fix(router): send 204 with empty string in preemptive mode instead of…
Browse files Browse the repository at this point in the history
… 404 (#409)
  • Loading branch information
pi0 authored Jun 20, 2023
1 parent add032a commit 2b2d596
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export function createAppEventHandler(stack: Stack, options: AppOptions) {
if (!event.node.res.writableEnded) {
throw createError({
statusCode: 404,
statusMessage: `Cannot find any route matching ${
statusMessage: `Cannot find any path matching ${
event.node.req.url || "/"
}.`,
});
Expand Down
23 changes: 17 additions & 6 deletions src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { createRouter as _createRouter } from "radix3";
import type { HTTPMethod, EventHandler } from "./types";
import { createError } from "./error";
import { eventHandler, toEventHandler } from "./event";
import { setResponseStatus } from "./utils";

export type RouterMethod = Lowercase<HTTPMethod>;
const RouterMethods: RouterMethod[] = [
Expand Down Expand Up @@ -103,19 +104,29 @@ export function createRouter(opts: CreateRouterOptions = {}): Router {
).toLowerCase() as RouterMethod;
const handler = matched.handlers[method] || matched.handlers.all;
if (!handler) {
throw createError({
statusCode: 405,
name: "Method Not Allowed",
statusMessage: `Method ${method} is not allowed on this route.`,
});
if (opts.preemptive || opts.preemtive) {
throw createError({
statusCode: 405,
name: "Method Not Allowed",
statusMessage: `Method ${method} is not allowed on this route.`,
});
} else {
return; // Let app match other handlers
}
}

// Add params
const params = matched.params || {};
event.context.params = params;

// Call handler
return handler(event);
return Promise.resolve(handler(event)).then((res) => {
if (res === undefined && (opts.preemptive || opts.preemtive)) {
setResponseStatus(event, 204);
return "";
}
return res;
});
});

return router;
Expand Down
39 changes: 39 additions & 0 deletions test/router.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,50 @@ describe("router", () => {
const res = await request.get("/404");
expect(res.status).toEqual(404);
});
});

describe("router (preemptive)", () => {
let app: App;
let router: Router;
let request: SuperTest<Test>;

beforeEach(() => {
app = createApp({ debug: false });
router = createRouter({ preemptive: true })
.get(
"/test",
eventHandler(() => "Test")
)
.get(
"/undefined",
eventHandler(() => undefined)
);
app.use(router);
request = supertest(toNodeListener(app));
});

it("Handle /test", async () => {
const res = await request.get("/test");
expect(res.text).toEqual("Test");
});

it("Handle /404", async () => {
const res = await request.get("/404");
expect(JSON.parse(res.text)).toMatchObject({
statusCode: 404,
statusMessage: "Cannot find any route matching /404.",
});
});

it("Not matching route method", async () => {
const res = await request.head("/test");
expect(res.status).toEqual(405);
});

it("Handle /undefined", async () => {
const res = await request.get("/undefined");
expect(res.text).toEqual("");
});
});

describe("getRouterParams", () => {
Expand Down

0 comments on commit 2b2d596

Please sign in to comment.