Handle routes that dont exist

This commit is contained in:
Jesse Wierzbinski 2024-03-10 17:29:25 -10:00
parent b7b82fee15
commit c98f788fec
No known key found for this signature in database
3 changed files with 46 additions and 11 deletions

View file

@ -161,6 +161,7 @@ export const rawRoutes = {
"/users/[uuid]/outbox": await import( "/users/[uuid]/outbox": await import(
serverPath + "/users/[uuid]/outbox/index.ts" serverPath + "/users/[uuid]/outbox/index.ts"
), ),
"/[...404]": await import(serverPath + "/[...404].ts"),
}; };
// Returns the route filesystem path when given a URL // Returns the route filesystem path when given a URL
@ -175,10 +176,13 @@ export const matchRoute = <T = Record<string, never>>(url: string) => {
return { return {
// @ts-expect-error TypeScript parses this as a defined object instead of an arbitrarily editable route file // @ts-expect-error TypeScript parses this as a defined object instead of an arbitrarily editable route file
file: rawRoutes[route.name] as Promise<{ file: rawRoutes[route.name] as Promise<
| {
meta: APIRouteMeta; meta: APIRouteMeta;
default: RouteHandler<T>; default: RouteHandler<T>;
}>, }
| undefined
>,
matchedRoute: route, matchedRoute: route,
}; };
}; };

View file

@ -1,4 +1,4 @@
import { jsonResponse } from "@response"; import { errorResponse, jsonResponse } from "@response";
import { matches } from "ip-matching"; import { matches } from "ip-matching";
import { getFromRequest } from "~database/entities/User"; import { getFromRequest } from "~database/entities/User";
import type { ConfigManager, ConfigType } from "config-manager"; import type { ConfigManager, ConfigType } from "config-manager";
@ -61,10 +61,22 @@ export const createServer = (
// There shouldn't be a performance hit after bundling right? // There shouldn't be a performance hit after bundling right?
const { matchRoute } = await import("~routes"); const { matchRoute } = await import("~routes");
const { file, matchedRoute } = matchRoute(req.url); const { file: filePromise, matchedRoute } = matchRoute(req.url);
if (matchedRoute) { const file = await filePromise;
const meta = (await file).meta;
if (matchedRoute && file == undefined) {
await logger.log(
LogLevel.ERROR,
"Server",
`Route file ${matchedRoute.filePath} not found or not registered in the routes file`
);
return errorResponse("Route not found", 500);
}
if (matchedRoute && file != undefined) {
const meta = file.meta;
// Check for allowed requests // Check for allowed requests
if (!meta.allowedMethods.includes(req.method as any)) { if (!meta.allowedMethods.includes(req.method as any)) {
@ -116,9 +128,7 @@ export const createServer = (
}); });
} }
return await ( return await file.default(req.clone(), matchedRoute, {
await file
).default(req.clone(), matchedRoute, {
auth, auth,
configManager, configManager,
parsedRequest, parsedRequest,

21
server/api/[...404].ts Normal file
View file

@ -0,0 +1,21 @@
import { apiRoute, applyConfig } from "@api";
import { errorResponse } from "@response";
export const meta = applyConfig({
allowedMethods: ["POST", "GET", "PUT", "PATCH", "DELETE"],
auth: {
required: false,
},
ratelimits: {
duration: 60,
max: 100,
},
route: "/[...404]",
});
/**
* Default catch-all route, returns a 404 error.
*/
export default apiRoute(() => {
return errorResponse("This API route does not exist", 404);
});