|
|
from apiflask import APIFlask, HTTPError
|
|
|
from apiflask.exceptions import _ValidationError
|
|
|
from iti.applications.common.utils import fail
|
|
|
from iti.applications.common.exceptions.biz_exp import BizException
|
|
|
from iti.applications.common.exceptions.permission import PermissionDeniedException
|
|
|
|
|
|
|
|
|
def init_error_handler(app: APIFlask):
|
|
|
"""
|
|
|
全局异常处理
|
|
|
"""
|
|
|
|
|
|
@app.errorhandler(Exception)
|
|
|
def handle_exception(error):
|
|
|
"""
|
|
|
未处理的异常处理
|
|
|
"""
|
|
|
try:
|
|
|
# 安全地获取错误信息
|
|
|
error_msg = str(error)
|
|
|
error_type = type(error).__name__
|
|
|
app.logger.error(
|
|
|
f"服务器错误 [{error_type}]: {error_msg}",
|
|
|
exc_info=True # 使用 exc_info 代替 stack_info,更安全
|
|
|
)
|
|
|
except Exception as log_error:
|
|
|
# 如果日志记录失败,使用最基本的方式记录
|
|
|
try:
|
|
|
app.logger.error(f"服务器错误(日志记录失败): {type(error).__name__}")
|
|
|
except:
|
|
|
pass # 完全失败则放弃日志记录
|
|
|
|
|
|
# 安全地返回错误信息
|
|
|
try:
|
|
|
error_data = str(error)
|
|
|
except:
|
|
|
error_data = type(error).__name__
|
|
|
|
|
|
return fail(message="服务器错误", code=500, data=error_data)
|
|
|
|
|
|
@app.errorhandler(400)
|
|
|
def handle_400(error):
|
|
|
"""
|
|
|
参数错误
|
|
|
"""
|
|
|
try:
|
|
|
app.logger.error(f"参数错误: {error}", exc_info=True)
|
|
|
except:
|
|
|
app.logger.error("参数错误(日志记录失败)")
|
|
|
|
|
|
return fail(
|
|
|
message=error.data.message
|
|
|
if error.data and "message" in error.data
|
|
|
else "参数错误",
|
|
|
code=400,
|
|
|
data=str(error),
|
|
|
)
|
|
|
|
|
|
@app.errorhandler(BizException)
|
|
|
def handle_biz_exception(error: BizException):
|
|
|
"""
|
|
|
业务异常处理
|
|
|
"""
|
|
|
try:
|
|
|
app.logger.error(f"业务异常: {error}")
|
|
|
except:
|
|
|
app.logger.error("业务异常(日志记录失败)")
|
|
|
return fail(error.message, code=error.code, data=error.data)
|
|
|
|
|
|
@app.errorhandler(PermissionDeniedException)
|
|
|
def handle_permission_denied_exception(error: PermissionDeniedException):
|
|
|
"""
|
|
|
权限不足异常处理
|
|
|
"""
|
|
|
try:
|
|
|
app.logger.error(f"权限不足: {error}")
|
|
|
except:
|
|
|
app.logger.error("权限不足(日志记录失败)")
|
|
|
return fail(message=error.message, code=error.code)
|
|
|
|
|
|
@app.error_processor
|
|
|
def handler_http_error(error: HTTPError):
|
|
|
"""
|
|
|
http异常处理
|
|
|
"""
|
|
|
try:
|
|
|
if isinstance(error, _ValidationError):
|
|
|
app.logger.error(f"参数验证错误: {error.detail}")
|
|
|
error.message = "参数验证错误"
|
|
|
else:
|
|
|
app.logger.error(
|
|
|
f"HTTP异常: {error.message} {error.status_code} {error.detail} {error.headers} {error.extra_data}"
|
|
|
)
|
|
|
except:
|
|
|
app.logger.error("HTTP异常(日志记录失败)")
|
|
|
|
|
|
return (
|
|
|
fail(message=error.message, code=error.status_code, data=error.detail),
|
|
|
200,
|
|
|
error.headers,
|
|
|
)
|