From af2c452e648f0343b60e922757a162f39941653c Mon Sep 17 00:00:00 2001 From: sianida26 Date: Mon, 6 May 2024 22:10:59 +0700 Subject: [PATCH] Added error class --- apps/backend/src/errors/DashboardError.ts | 44 +++++++++++++++++++ apps/backend/src/index.ts | 24 +++++----- .../src/types/DashboardErrorParameter.d.ts | 11 +++++ 3 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 apps/backend/src/errors/DashboardError.ts create mode 100644 apps/backend/src/types/DashboardErrorParameter.d.ts diff --git a/apps/backend/src/errors/DashboardError.ts b/apps/backend/src/errors/DashboardError.ts new file mode 100644 index 0000000..a696a66 --- /dev/null +++ b/apps/backend/src/errors/DashboardError.ts @@ -0,0 +1,44 @@ +import { StatusCode } from "hono/utils/http-status"; +import DashboardErrorParameter from "../types/DashboardErrorParameter"; + +class DashboardError extends Error { + public readonly errorCode: string; + public readonly statusCode: StatusCode = 500; + public readonly message: string; + public readonly formErrors?: Record; + public readonly severity: "CRITICAL" | "HIGH" | "MEDIUM" | "LOW" = + "CRITICAL"; + + constructor(options: DashboardErrorParameter) { + super(); + + this.errorCode = options.errorCode; + this.statusCode = options.statusCode ?? this.statusCode; + this.message = options.message; + this.formErrors = options.formErrors; + + Object.setPrototypeOf(this, new.target.prototype); + } +} + +export const notFound = (options?: Partial) => { + throw new DashboardError({ + errorCode: options?.errorCode ?? "NOT_FOUND", + message: options?.message ?? "The requested data is not found", + formErrors: options?.formErrors, + severity: options?.severity ?? "LOW", + statusCode: options?.statusCode ?? 404, + }); +}; + +export const unauthorized = (options?: Partial) => { + throw new DashboardError({ + errorCode: options?.errorCode ?? "UNAUTHORIZED", + message: options?.message ?? "Unauthorized", + formErrors: options?.formErrors, + severity: options?.severity ?? "LOW", + statusCode: options?.statusCode ?? 401, + }); +}; + +export default DashboardError; diff --git a/apps/backend/src/index.ts b/apps/backend/src/index.ts index 1d1473a..23e9d5f 100644 --- a/apps/backend/src/index.ts +++ b/apps/backend/src/index.ts @@ -11,6 +11,7 @@ import { getSignedCookie } from "hono/cookie"; import dashboardRoutes from "./routes/dashboard/routes"; import rolesRoute from "./routes/roles/route"; import { logger } from "hono/logger"; +import DashboardError from "./errors/DashboardError"; configDotenv(); @@ -20,19 +21,6 @@ export type HonoVariables = { const app = new Hono<{ Variables: HonoVariables }>(); -// app.use(async (c, next) => { -// const authHeader = c.req.header("Authorization"); - -// if (authHeader && authHeader.startsWith("Bearer ")) { -// const token = authHeader.substring(7); -// const payload = await verifyAccessToken(token); - -// if (payload) c.set("uid", payload.uid); -// } - -// await next(); -// }); - const routes = app .use(logger()) .use( @@ -91,6 +79,16 @@ const routes = app .route("/dashboard", dashboardRoutes) .route("/roles", rolesRoute) .onError((err, c) => { + if (err instanceof DashboardError) { + return c.json( + { + message: err.message, + errorCode: err.errorCode, + formErrors: err.formErrors, + }, + err.statusCode + ); + } if (err instanceof HTTPException) { console.log(err); return c.json( diff --git a/apps/backend/src/types/DashboardErrorParameter.d.ts b/apps/backend/src/types/DashboardErrorParameter.d.ts new file mode 100644 index 0000000..63d49f5 --- /dev/null +++ b/apps/backend/src/types/DashboardErrorParameter.d.ts @@ -0,0 +1,11 @@ +import { StatusCode } from "hono/utils/http-status"; + +interface DashboardErrorParameter { + errorCode: string; + statusCode?: StatusCode; + message: string; + formErrors?: Record; + severity?: "CRITICAL" | "HIGH" | "MEDIUM" | "LOW"; +} + +export default DashboardErrorParameter;