import { prettifyError, ZodError } from "zod/v4"; export const StatusCodes: Record = { 400: "Bad Request", 403: "Forbidden", 404: "Not Found", 408: "Request Timeout", 409: "Conflict", 429: "Too Many Requests", 499: "Client Closed Request", 500: "Internal Server Error", }; export class BaseError extends Error { status: number; constructor(message: string, status: number, cause?: Error) { const statusText = StatusCodes[status] || "Unknown"; super(`${status} ${statusText}: ${message}`); this.name = this.constructor.name; this.status = status; this.cause = cause; } } export class CancellationError extends BaseError { constructor(reason: string, cause?: Error) { super(`${reason} was cancelled`, 499, cause); } } export class AuthError extends BaseError { constructor(reason: string, cause?: Error) { super(`authentication failed: ${reason}`, 403, cause); } } export class ValidationError extends BaseError { constructor(zodError: ZodError, cause?: Error) { super(`validation failed: ${prettifyError(zodError)}`, 400, cause); } } export class NotFoundError extends BaseError { constructor(resource: string, cause?: Error) { super(`${resource} not found`, 404, cause); } } export class ConflictError extends BaseError { constructor(reason: string, cause?: Error) { super(`conflict: ${reason}`, 409, cause); } } export class RateLimitError extends BaseError { constructor(reason: string, cause?: Error) { super(`rate limit exceeded: ${reason}`, 429, cause); } } export class NormalizedError extends Error { value: unknown; constructor(value: unknown, cause?: Error) { super(cause?.message || String(value)); this.value = value; } } export function normalizeError(value: unknown) { if (value instanceof Error) { return value; } else { return new NormalizedError(value); } }