| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
| export interface ErrorCodeDef {
|
| code: string;
|
| message: string;
|
| httpStatus: number;
|
| category: string;
|
| }
|
|
|
| interface ErrorDetails {
|
| detail?: string;
|
| requestId?: string;
|
| retryAfter?: number;
|
| }
|
|
|
| export const ERROR_CODES: Record<string, ErrorCodeDef> = {
|
|
|
| AUTH_001: {
|
| code: "AUTH_001",
|
| message: "Authentication required",
|
| httpStatus: 401,
|
| category: "AUTH",
|
| },
|
| AUTH_002: { code: "AUTH_002", message: "Invalid API key", httpStatus: 401, category: "AUTH" },
|
| AUTH_003: { code: "AUTH_003", message: "API key expired", httpStatus: 401, category: "AUTH" },
|
| AUTH_004: {
|
| code: "AUTH_004",
|
| message: "Insufficient permissions",
|
| httpStatus: 403,
|
| category: "AUTH",
|
| },
|
| AUTH_005: { code: "AUTH_005", message: "Account locked", httpStatus: 423, category: "AUTH" },
|
| AUTH_006: {
|
| code: "AUTH_006",
|
| message: "No credentials for provider",
|
| httpStatus: 400,
|
| category: "AUTH",
|
| },
|
|
|
|
|
| PROXY_001: {
|
| code: "PROXY_001",
|
| message: "Proxy connection failed",
|
| httpStatus: 502,
|
| category: "PROXY",
|
| },
|
| PROXY_002: { code: "PROXY_002", message: "Proxy timeout", httpStatus: 504, category: "PROXY" },
|
| PROXY_003: {
|
| code: "PROXY_003",
|
| message: "All proxies exhausted",
|
| httpStatus: 503,
|
| category: "PROXY",
|
| },
|
|
|
|
|
| RATE_001: {
|
| code: "RATE_001",
|
| message: "Rate limit exceeded",
|
| httpStatus: 429,
|
| category: "RATE_LIMIT",
|
| },
|
| RATE_002: {
|
| code: "RATE_002",
|
| message: "Daily budget exceeded",
|
| httpStatus: 429,
|
| category: "RATE_LIMIT",
|
| },
|
| RATE_003: {
|
| code: "RATE_003",
|
| message: "All accounts rate-limited",
|
| httpStatus: 503,
|
| category: "RATE_LIMIT",
|
| },
|
|
|
|
|
| MODEL_001: { code: "MODEL_001", message: "Model not found", httpStatus: 404, category: "MODEL" },
|
| MODEL_002: {
|
| code: "MODEL_002",
|
| message: "Ambiguous model identifier",
|
| httpStatus: 400,
|
| category: "MODEL",
|
| },
|
| MODEL_003: {
|
| code: "MODEL_003",
|
| message: "Model temporarily unavailable",
|
| httpStatus: 503,
|
| category: "MODEL",
|
| },
|
|
|
|
|
| PROVIDER_001: {
|
| code: "PROVIDER_001",
|
| message: "Provider error",
|
| httpStatus: 502,
|
| category: "PROVIDER",
|
| },
|
| PROVIDER_002: {
|
| code: "PROVIDER_002",
|
| message: "Provider timeout",
|
| httpStatus: 504,
|
| category: "PROVIDER",
|
| },
|
| PROVIDER_003: {
|
| code: "PROVIDER_003",
|
| message: "Provider not configured",
|
| httpStatus: 400,
|
| category: "PROVIDER",
|
| },
|
|
|
|
|
| VALID_001: {
|
| code: "VALID_001",
|
| message: "Invalid request body",
|
| httpStatus: 400,
|
| category: "VALIDATION",
|
| },
|
| VALID_002: {
|
| code: "VALID_002",
|
| message: "Missing required field",
|
| httpStatus: 400,
|
| category: "VALIDATION",
|
| },
|
| VALID_003: {
|
| code: "VALID_003",
|
| message: "Input sanitization blocked",
|
| httpStatus: 400,
|
| category: "VALIDATION",
|
| },
|
|
|
|
|
| INTERNAL_001: {
|
| code: "INTERNAL_001",
|
| message: "Internal server error",
|
| httpStatus: 500,
|
| category: "INTERNAL",
|
| },
|
| INTERNAL_002: {
|
| code: "INTERNAL_002",
|
| message: "Database error",
|
| httpStatus: 500,
|
| category: "INTERNAL",
|
| },
|
| INTERNAL_003: {
|
| code: "INTERNAL_003",
|
| message: "Circuit breaker open",
|
| httpStatus: 503,
|
| category: "INTERNAL",
|
| },
|
| };
|
|
|
| export function createErrorResponse(code: string, details: ErrorDetails = {}) {
|
| const def = ERROR_CODES[code];
|
| if (!def) {
|
| return {
|
| error: {
|
| code: "INTERNAL_001",
|
| message: `Unknown error code: ${code}`,
|
| category: "INTERNAL",
|
| },
|
| status: 500,
|
| };
|
| }
|
|
|
| const response: any = {
|
| error: {
|
| code: def.code,
|
| message: def.message,
|
| category: def.category,
|
| ...(details.detail ? { detail: details.detail } : {}),
|
| ...(details.requestId ? { requestId: details.requestId } : {}),
|
| },
|
| status: def.httpStatus,
|
| };
|
|
|
| if (details.retryAfter) {
|
| response.retryAfter = details.retryAfter;
|
| }
|
|
|
| return response;
|
| }
|
|
|
| export function getErrorsByCategory(category: string): ErrorCodeDef[] {
|
| return Object.values(ERROR_CODES).filter((e) => e.category === category);
|
| }
|
|
|