60 lines
1.2 KiB
TypeScript
60 lines
1.2 KiB
TypeScript
import { ZodError } from "dbtype";
|
|
import type { Context, Next } from "koa";
|
|
|
|
export interface ErrorFormat {
|
|
code: number;
|
|
message: string;
|
|
detail?: string;
|
|
}
|
|
|
|
class ClientRequestError implements Error {
|
|
name: string;
|
|
message: string;
|
|
stack?: string | undefined;
|
|
code: number;
|
|
|
|
constructor(code: number, message: string) {
|
|
this.name = "client request error";
|
|
this.message = message;
|
|
this.code = code;
|
|
}
|
|
}
|
|
|
|
const code_to_message_table: { [key: number]: string | undefined } = {
|
|
400: "BadRequest",
|
|
404: "NotFound",
|
|
};
|
|
|
|
export const error_handler = async (ctx: Context, next: Next) => {
|
|
try {
|
|
await next();
|
|
} catch (err) {
|
|
if (err instanceof ClientRequestError) {
|
|
const body: ErrorFormat = {
|
|
code: err.code,
|
|
message: code_to_message_table[err.code] ?? "",
|
|
detail: err.message,
|
|
};
|
|
ctx.status = err.code;
|
|
ctx.body = body;
|
|
}
|
|
else if (err instanceof ZodError) {
|
|
const body: ErrorFormat = {
|
|
code: 400,
|
|
message: "BadRequest",
|
|
detail: err.errors.map((x) => x.message).join(", "),
|
|
};
|
|
ctx.status = 400;
|
|
ctx.body = body;
|
|
}
|
|
else {
|
|
throw err;
|
|
}
|
|
}
|
|
};
|
|
|
|
export const sendError = (code: number, message?: string) => {
|
|
throw new ClientRequestError(code, message ?? "");
|
|
};
|
|
|
|
export default error_handler;
|