65 lines
1.7 KiB
TypeScript
65 lines
1.7 KiB
TypeScript
export class ApiError extends Error {
|
|
statusCode: number;
|
|
code: string;
|
|
details?: unknown;
|
|
|
|
constructor(statusCode: number, code: string, message: string, details?: unknown) {
|
|
super(message);
|
|
this.name = "ApiError";
|
|
this.statusCode = statusCode;
|
|
this.code = code;
|
|
this.details = details;
|
|
}
|
|
}
|
|
|
|
export function badRequest(code: string, message: string, details?: unknown) {
|
|
return new ApiError(400, code, message, details);
|
|
}
|
|
|
|
export function unauthorized(code: string, message: string, details?: unknown) {
|
|
return new ApiError(401, code, message, details);
|
|
}
|
|
|
|
export function forbidden(code: string, message: string, details?: unknown) {
|
|
return new ApiError(403, code, message, details);
|
|
}
|
|
|
|
export function notFound(code: string, message: string, details?: unknown) {
|
|
return new ApiError(404, code, message, details);
|
|
}
|
|
|
|
export function conflict(code: string, message: string, details?: unknown) {
|
|
return new ApiError(409, code, message, details);
|
|
}
|
|
|
|
export function toErrorBody(err: unknown, requestId: string) {
|
|
if (err instanceof ApiError) {
|
|
return {
|
|
statusCode: err.statusCode,
|
|
body: {
|
|
ok: false,
|
|
code: err.code,
|
|
message: err.message,
|
|
requestId,
|
|
...(err.details !== undefined ? { details: err.details } : {}),
|
|
},
|
|
};
|
|
}
|
|
|
|
const fallback = err as { statusCode?: number; code?: string; message?: string };
|
|
const statusCode =
|
|
typeof fallback?.statusCode === "number" ? fallback.statusCode : 500;
|
|
return {
|
|
statusCode,
|
|
body: {
|
|
ok: false,
|
|
code: fallback?.code ?? "INTERNAL",
|
|
message:
|
|
statusCode >= 500
|
|
? "Something went wrong"
|
|
: fallback?.message ?? "Bad request",
|
|
requestId,
|
|
},
|
|
};
|
|
}
|