Add HttpError custom exception to js runtime.

This commit is contained in:
Sebastian Jeltsch
2024-11-14 15:21:27 +01:00
parent 8fa26c246f
commit ad8839f28d
4 changed files with 78 additions and 1 deletions

View File

@@ -1,4 +1,4 @@
import { addRoute, parsePath, query, htmlHandler, jsonHandler, stringHandler } from "../trailbase.js";
import { addRoute, parsePath, query, htmlHandler, jsonHandler, stringHandler, HttpError } from "../trailbase.js";
import type { JsonRequestType, ParsedPath, StringRequestType } from "../trailbase.d.ts";
addRoute("GET", "/test", stringHandler(async (req: StringRequestType) => {
@@ -43,3 +43,7 @@ addRoute("GET", "/json", jsonHandler((_req: JsonRequestType) => {
}
};
}));
addRoute("GET", "/error", jsonHandler((_req: JsonRequestType) => {
throw new HttpError(418, "I'm a teapot");
}));

View File

@@ -77,6 +77,13 @@ export declare enum StatusCodes {
INSUFFICIENT_STORAGE = 507,
NETWORK_AUTHENTICATION_REQUIRED = 511
}
export declare class HttpError extends Error {
readonly statusCode: number;
readonly headers: [string, string][] | undefined;
constructor(statusCode: number, message?: string, headers?: [string, string][]);
toString(): string;
toResponse(): ResponseType;
}
export type StringRequestType = {
uri: string;
params: PathParamsType;

View File

@@ -346,6 +346,26 @@ export var StatusCodes;
/// gain network access.
StatusCodes[StatusCodes["NETWORK_AUTHENTICATION_REQUIRED"] = 511] = "NETWORK_AUTHENTICATION_REQUIRED";
})(StatusCodes || (StatusCodes = {}));
export class HttpError extends Error {
statusCode;
headers;
constructor(statusCode, message, headers) {
super(message);
this.statusCode = statusCode;
this.headers = headers;
}
toString() {
return `HttpError(${this.statusCode}, ${this.message})`;
}
toResponse() {
const m = this.message;
return {
headers: this.headers,
status: this.statusCode,
body: m !== "" ? encodeFallback(m) : undefined,
};
}
}
export function stringHandler(f) {
return async (req) => {
try {
@@ -373,6 +393,9 @@ export function stringHandler(f) {
};
}
catch (err) {
if (err instanceof HttpError) {
return err.toResponse();
}
return {
status: StatusCodes.INTERNAL_SERVER_ERROR,
body: encodeFallback(`Uncaught error: ${err}`),
@@ -408,6 +431,9 @@ export function htmlHandler(f) {
};
}
catch (err) {
if (err instanceof HttpError) {
return err.toResponse();
}
return {
status: StatusCodes.INTERNAL_SERVER_ERROR,
body: encodeFallback(`Uncaught error: ${err}`),
@@ -444,6 +470,9 @@ export function jsonHandler(f) {
};
}
catch (err) {
if (err instanceof HttpError) {
return err.toResponse();
}
return {
headers: [["content-type", "application/json"]],
status: StatusCodes.INTERNAL_SERVER_ERROR,

View File

@@ -365,6 +365,34 @@ export enum StatusCodes {
NETWORK_AUTHENTICATION_REQUIRED = 511,
}
export class HttpError extends Error {
readonly statusCode: number;
readonly headers: [string, string][] | undefined;
constructor(
statusCode: number,
message?: string,
headers?: [string, string][],
) {
super(message);
this.statusCode = statusCode;
this.headers = headers;
}
public override toString(): string {
return `HttpError(${this.statusCode}, ${this.message})`;
}
toResponse(): ResponseType {
const m = this.message;
return {
headers: this.headers,
status: this.statusCode,
body: m !== "" ? encodeFallback(m) : undefined,
};
}
}
export type StringRequestType = {
uri: string;
params: PathParamsType;
@@ -408,6 +436,9 @@ export function stringHandler(
body: respBody ? encodeFallback(respBody) : undefined,
};
} catch (err) {
if (err instanceof HttpError) {
return err.toResponse();
}
return {
status: StatusCodes.INTERNAL_SERVER_ERROR,
body: encodeFallback(`Uncaught error: ${err}`),
@@ -454,6 +485,9 @@ export function htmlHandler(
body: respBody ? encodeFallback(respBody) : undefined,
};
} catch (err) {
if (err instanceof HttpError) {
return err.toResponse();
}
return {
status: StatusCodes.INTERNAL_SERVER_ERROR,
body: encodeFallback(`Uncaught error: ${err}`),
@@ -507,6 +541,9 @@ export function jsonHandler(
body: encodeFallback(JSON.stringify(resp)),
};
} catch (err) {
if (err instanceof HttpError) {
return err.toResponse();
}
return {
headers: [["content-type", "application/json"]],
status: StatusCodes.INTERNAL_SERVER_ERROR,