import type { ApiErrorBody } from '../schemas/api.js'; import { ERROR_MESSAGES, type ErrorCode } from './codes.js'; /** * 前后端共用的 API 错误对象。 * - 服务端:AllExceptionsFilter 用它把异常序列化成统一错误体; * - 前端:请求层把错误体还原成 ApiError,保留 trace_id 便于用户报障。 */ export class ApiError extends Error { readonly code: ErrorCode; readonly status: number; readonly details?: unknown; readonly traceId: string; constructor(params: { code: ErrorCode; message?: string; details?: unknown; traceId?: string }) { super(params.message ?? ERROR_MESSAGES[params.code]); this.name = 'ApiError'; this.code = params.code; this.status = Math.floor(params.code / 100); this.details = params.details; this.traceId = params.traceId ?? ''; } toBody(): ApiErrorBody { return { code: this.code, message: this.message, ...(this.details === undefined ? {} : { details: this.details }), trace_id: this.traceId, }; } }