add custom not found handler

This commit is contained in:
HorizonCode 2023-05-11 09:32:18 +02:00
parent 63be7aba60
commit 93f5bd30b9
2 changed files with 79 additions and 23 deletions

View File

@ -3,6 +3,19 @@ import { HTTPServer } from "../http_server.ts";
const httpServer = new HTTPServer(); const httpServer = new HTTPServer();
httpServer.error((req, _rep) => {
return JSON.stringify(
{
code: Status.NotFound,
message: "Route not found!",
path: req.path,
url: req.url
},
null,
2,
);
})
httpServer.add("GET", "/", (req, rep) => { httpServer.add("GET", "/", (req, rep) => {
rep.status(Status.Teapot) rep.status(Status.Teapot)
.header("working", "true") .header("working", "true")

View File

@ -28,6 +28,7 @@ export class HTTPServer {
private routes = new Map<string, Route>(); private routes = new Map<string, Route>();
private staticLocalDir?: string; private staticLocalDir?: string;
private staticServePath?: string; private staticServePath?: string;
private notFoundHandler?: RouteHandler;
async listen(options: ListenOptions) { async listen(options: ListenOptions) {
this.server = Deno.listen({ this.server = Deno.listen({
@ -56,6 +57,8 @@ export class HTTPServer {
for await (const requestEvent of httpConn) { for await (const requestEvent of httpConn) {
const url = new URL(requestEvent.request.url); const url = new URL(requestEvent.request.url);
const filepath = decodeURIComponent(url.pathname); const filepath = decodeURIComponent(url.pathname);
const routeRequest = new RouteRequest(requestEvent.request);
const routeReply: RouteReply = new RouteReply();
if (this.staticServePath && filepath.startsWith(this.staticServePath)) { if (this.staticServePath && filepath.startsWith(this.staticServePath)) {
const fileDir = filepath.split("/").slice(2).join("/"); const fileDir = filepath.split("/").slice(2).join("/");
@ -69,17 +72,37 @@ export class HTTPServer {
file = await Deno.open(pathLoc, { read: true }); file = await Deno.open(pathLoc, { read: true });
} catch { } catch {
// If the file cannot be opened, return a "404 Not Found" response // If the file cannot be opened, return a "404 Not Found" response
await requestEvent.respondWith( if (this.notFoundHandler) {
new Response( routeReply.status(Status.NotFound);
JSON.stringify({ routeReply.type("application/json");
code: 404, const notNoundHandle = await this.notFoundHandler(
message: `File ${filepath} not found!`, routeRequest,
routeReply,
);
await requestEvent.respondWith(
new Response(notNoundHandle as string, {
status: routeReply.statusCode,
headers: routeReply.headers,
statusText: STATUS_TEXT[routeReply.statusCode],
}), }),
{ );
status: Status.NotFound, continue;
}, } else {
), await requestEvent.respondWith(
); new Response(
JSON.stringify({
code: 404,
message: `File ${filepath} not found!`,
}),
{
status: Status.NotFound,
headers: {
"Content-Type": "application/json",
},
},
),
);
}
continue; continue;
} }
@ -88,8 +111,6 @@ export class HTTPServer {
await requestEvent.respondWith(response); await requestEvent.respondWith(response);
return; return;
} }
const routeRequest = new RouteRequest(requestEvent.request);
const routeReply: RouteReply = new RouteReply();
const routeName = `${requestEvent.request.method}@${filepath}`; const routeName = `${requestEvent.request.method}@${filepath}`;
let route = this.routes.has(routeName) let route = this.routes.has(routeName)
? this.routes.get(routeName) ? this.routes.get(routeName)
@ -141,21 +162,43 @@ export class HTTPServer {
continue; continue;
} }
if (this.notFoundHandler) {
await requestEvent.respondWith( routeReply.status(Status.NotFound);
new Response( routeReply.type("application/json");
JSON.stringify({ const notNoundHandle = await this.notFoundHandler(
code: 404, routeRequest,
message: `Route ${routeName} not found!`, routeReply,
);
await requestEvent.respondWith(
new Response(notNoundHandle as string, {
status: routeReply.statusCode,
headers: routeReply.headers,
statusText: STATUS_TEXT[routeReply.statusCode],
}), }),
{ );
status: Status.NotFound, } else {
}, await requestEvent.respondWith(
), new Response(
); JSON.stringify({
code: 404,
message: `Route ${routeName} not found!`,
}),
{
status: Status.NotFound,
headers: {
"Content-Type": "application/json",
},
},
),
);
}
} }
} }
error(handler: RouteHandler) {
this.notFoundHandler = handler;
}
get(path: string, handler: RouteHandler) { get(path: string, handler: RouteHandler) {
this.add("GET", path, handler); this.add("GET", path, handler);
} }