You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
51 lines
1.8 KiB
51 lines
1.8 KiB
"""
|
|
API装饰器工具
|
|
"""
|
|
import functools
|
|
from typing import Callable, Any
|
|
from fastapi import HTTPException, status
|
|
from app.utils.structured_log import get_structured_logger, LogLevel
|
|
|
|
logger = get_structured_logger(__name__, LogLevel.INFO)
|
|
|
|
def handle_api_errors(func: Callable) -> Callable:
|
|
"""API错误处理装饰器"""
|
|
@functools.wraps(func)
|
|
async def wrapper(*args, **kwargs) -> Any:
|
|
try:
|
|
return await func(*args, **kwargs)
|
|
except HTTPException:
|
|
# 重新抛出HTTP异常
|
|
raise
|
|
except ValueError as e:
|
|
# 参数验证错误
|
|
logger.warning(f"参数验证错误: {func.__name__}, 错误: {e}")
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail=f"参数验证错误: {str(e)}"
|
|
)
|
|
except KeyError as e:
|
|
# 资源不存在错误
|
|
logger.warning(f"资源不存在: {func.__name__}, 错误: {e}")
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail=f"资源不存在: {str(e)}"
|
|
)
|
|
except Exception as e:
|
|
# 其他未预期的错误
|
|
logger.error(f"API执行错误: {func.__name__}, 错误: {e}")
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail=f"服务器内部错误: {str(e)}"
|
|
)
|
|
return wrapper
|
|
|
|
def validate_resource_exists(resource_type: str):
|
|
"""验证资源是否存在的装饰器"""
|
|
def decorator(func: Callable) -> Callable:
|
|
@functools.wraps(func)
|
|
async def wrapper(*args, **kwargs) -> Any:
|
|
# 这里可以添加通用的资源存在性验证逻辑
|
|
return await func(*args, **kwargs)
|
|
return wrapper
|
|
return decorator
|