Files
OmniRoute/src/shared/constants/errorCodes.ts
diegosouzapw 71d14209a4 feat: OmniRoute v1.0.0 — Intelligent AI Gateway & Universal LLM Proxy
OmniRoute is an intelligent API gateway that unifies 20+ AI providers behind a single
OpenAI-compatible endpoint. Features include intelligent routing with 6 strategies,
multi-format translation (OpenAI/Claude/Gemini/Responses API), circuit breakers,
semantic caching, combo fallback chains, real-time health monitoring, and a full
dashboard with provider management, analytics, and CLI tool integration.

Key highlights:
- 20+ providers (Claude Code, Codex, Gemini CLI, GitHub Copilot, iFlow, Qwen, Kiro, etc.)
- 6 routing strategies (Fill First, Round Robin, P2C, Random, Least Used, Cost Optimized)
- Export/Import database backup with full archive support
- Translator Playground with 4 modes (Playground, Chat Tester, Test Bench, Live Monitor)
- 100% TypeScript across src/ and open-sse/
- Docker support with multi-stage builds
- Comprehensive documentation and 9 dashboard screenshots
2026-02-18 00:02:15 -03:00

101 lines
4.2 KiB
TypeScript

/**
* Error Codes Catalog — T-22
*
* Centralized error code registry for consistent API error responses.
* Each code has a category prefix, numeric ID, message, and HTTP status.
*
* Usage:
* import { ERROR_CODES, createErrorResponse } from "@/shared/constants/errorCodes";
* return createErrorResponse("AUTH_001", { detail: "Token expired" });
*
* @module shared/constants/errorCodes
*/
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 ──
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 ──
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 Limiting ──
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 / Routing ──
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 ──
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" },
// ── Validation ──
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 ──
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);
}