1"""OpenAI-style structured errors."""23from __future__ import annotations45from fastapi import Request6from fastapi.responses import JSONResponse789class APIError(Exception):10 status_code = 40011 error_type = "invalid_request_error"12 code = "INVALID_REQUEST"1314 def __init__(self, message: str, *, status_code: int | None = None, error_type: str | None = None,15 code: str | None = None, param: str | None = None, extra: dict | None = None):16 super().__init__(message)17 self.message = message18 if status_code is not None:19 self.status_code = status_code20 if error_type is not None:21 self.error_type = error_type22 if code is not None:23 self.code = code24 self.param = param25 self.extra = extra or {}2627 def to_dict(self) -> dict:28 err = {"message": self.message, "type": self.error_type, "code": self.code, "param": self.param}29 err.update(self.extra)30 return {"error": err}313233class ModelNotFound(APIError):34 status_code = 40435 error_type = "invalid_request_error"36 code = "MODEL_NOT_FOUND"373839class ModelTooLarge(APIError):40 status_code = 50741 error_type = "model_memory_error"42 code = "MODEL_TOO_LARGE"434445class ModelIncompatible(APIError):46 status_code = 42247 error_type = "model_compatibility_error"48 code = "MODEL_INCOMPATIBLE"495051class ModelLoadError(APIError):52 status_code = 50353 error_type = "model_load_error"54 code = "MODEL_LOAD_FAILED"555657class ModelLoadTimeout(ModelLoadError):58 code = "MODEL_LOAD_TIMEOUT"596061class WorkerCrashed(APIError):62 status_code = 50363 error_type = "runtime_error"64 code = "WORKER_CRASHED"656667class GenerationTimeout(APIError):68 status_code = 50469 error_type = "runtime_error"70 code = "GENERATION_TIMEOUT"717273class ContextTooLarge(APIError):74 status_code = 40075 error_type = "invalid_request_error"76 code = "CONTEXT_TOO_LARGE"777879class InsufficientDisk(APIError):80 status_code = 50781 error_type = "storage_error"82 code = "INSUFFICIENT_DISK"838485class DownloadError(APIError):86 status_code = 50287 error_type = "download_error"88 code = "DOWNLOAD_FAILED"899091class AuthError(APIError):92 status_code = 40193 error_type = "authentication_error"94 code = "INVALID_API_KEY"959697class Forbidden(APIError):98 status_code = 40399 error_type = "permission_error"100 code = "FORBIDDEN"101102103class RateLimited(APIError):104 status_code = 429105 error_type = "rate_limit_error"106 code = "RATE_LIMITED"107108109class Conflict(APIError):110 status_code = 409111 error_type = "invalid_request_error"112 code = "CONFLICT"113114115class RuntimeUnsupported(APIError):116 status_code = 422117 error_type = "model_compatibility_error"118 code = "RUNTIME_UNSUPPORTED"119120121async def api_error_handler(_: Request, exc: APIError) -> JSONResponse:122 return JSONResponse(status_code=exc.status_code, content=exc.to_dict())123