mirror of
https://github.com/snailyp/gemini-balance.git
synced 2026-05-17 14:47:35 +08:00
重构项目目录结构,提高代码组织性和可维护性 将schemas目录重命名为domain,更好地表达领域模型概念 将services目录细分为service/chat、service/image等子目录 将api目录重命名为router,更符合FastAPI惯例 创建utils目录存放通用工具函数 更新FastAPI应用程序生命周期管理 替换已弃用的on_event方法为推荐的lifespan事件处理器 添加应用程序关闭时的日志记录 代码质量改进 抽取常量到constants.py,减少硬编码值 添加helpers.py提供通用工具函数 优化配置管理,使用环境变量和默认值 完善文档字符串,提高代码可读性
134 lines
4.3 KiB
Python
134 lines
4.3 KiB
Python
"""
|
|
异常处理模块,定义应用程序中使用的自定义异常和异常处理器
|
|
"""
|
|
from fastapi import Request, FastAPI
|
|
from fastapi.responses import JSONResponse
|
|
from fastapi.exceptions import RequestValidationError
|
|
from starlette.exceptions import HTTPException as StarletteHTTPException
|
|
|
|
from app.logger.logger import get_main_logger
|
|
|
|
logger = get_main_logger()
|
|
|
|
|
|
class APIError(Exception):
|
|
"""API错误基类"""
|
|
def __init__(self, status_code: int, detail: str, error_code: str = None):
|
|
self.status_code = status_code
|
|
self.detail = detail
|
|
self.error_code = error_code or "api_error"
|
|
super().__init__(self.detail)
|
|
|
|
|
|
class AuthenticationError(APIError):
|
|
"""认证错误"""
|
|
def __init__(self, detail: str = "Authentication failed"):
|
|
super().__init__(status_code=401, detail=detail, error_code="authentication_error")
|
|
|
|
|
|
class AuthorizationError(APIError):
|
|
"""授权错误"""
|
|
def __init__(self, detail: str = "Not authorized to access this resource"):
|
|
super().__init__(status_code=403, detail=detail, error_code="authorization_error")
|
|
|
|
|
|
class ResourceNotFoundError(APIError):
|
|
"""资源未找到错误"""
|
|
def __init__(self, detail: str = "Resource not found"):
|
|
super().__init__(status_code=404, detail=detail, error_code="resource_not_found")
|
|
|
|
|
|
class ModelNotSupportedError(APIError):
|
|
"""模型不支持错误"""
|
|
def __init__(self, model: str):
|
|
super().__init__(
|
|
status_code=400,
|
|
detail=f"Model {model} is not supported",
|
|
error_code="model_not_supported"
|
|
)
|
|
|
|
|
|
class APIKeyError(APIError):
|
|
"""API密钥错误"""
|
|
def __init__(self, detail: str = "Invalid or expired API key"):
|
|
super().__init__(status_code=401, detail=detail, error_code="api_key_error")
|
|
|
|
|
|
class ServiceUnavailableError(APIError):
|
|
"""服务不可用错误"""
|
|
def __init__(self, detail: str = "Service temporarily unavailable"):
|
|
super().__init__(status_code=503, detail=detail, error_code="service_unavailable")
|
|
|
|
|
|
def setup_exception_handlers(app: FastAPI) -> None:
|
|
"""
|
|
设置应用程序的异常处理器
|
|
|
|
Args:
|
|
app: FastAPI应用程序实例
|
|
"""
|
|
@app.exception_handler(APIError)
|
|
async def api_error_handler(request: Request, exc: APIError):
|
|
"""处理API错误"""
|
|
logger.error(f"API Error: {exc.detail} (Code: {exc.error_code})")
|
|
return JSONResponse(
|
|
status_code=exc.status_code,
|
|
content={
|
|
"error": {
|
|
"code": exc.error_code,
|
|
"message": exc.detail
|
|
}
|
|
}
|
|
)
|
|
|
|
@app.exception_handler(StarletteHTTPException)
|
|
async def http_exception_handler(request: Request, exc: StarletteHTTPException):
|
|
"""处理HTTP异常"""
|
|
logger.error(f"HTTP Exception: {exc.detail} (Status: {exc.status_code})")
|
|
return JSONResponse(
|
|
status_code=exc.status_code,
|
|
content={
|
|
"error": {
|
|
"code": "http_error",
|
|
"message": exc.detail
|
|
}
|
|
}
|
|
)
|
|
|
|
@app.exception_handler(RequestValidationError)
|
|
async def validation_exception_handler(request: Request, exc: RequestValidationError):
|
|
"""处理请求验证错误"""
|
|
error_details = []
|
|
for error in exc.errors():
|
|
error_details.append({
|
|
"loc": error["loc"],
|
|
"msg": error["msg"],
|
|
"type": error["type"]
|
|
})
|
|
|
|
logger.error(f"Validation Error: {error_details}")
|
|
return JSONResponse(
|
|
status_code=422,
|
|
content={
|
|
"error": {
|
|
"code": "validation_error",
|
|
"message": "Request validation failed",
|
|
"details": error_details
|
|
}
|
|
}
|
|
)
|
|
|
|
@app.exception_handler(Exception)
|
|
async def general_exception_handler(request: Request, exc: Exception):
|
|
"""处理通用异常"""
|
|
logger.exception(f"Unhandled Exception: {str(exc)}")
|
|
return JSONResponse(
|
|
status_code=500,
|
|
content={
|
|
"error": {
|
|
"code": "internal_server_error",
|
|
"message": "An unexpected error occurred"
|
|
}
|
|
}
|
|
)
|