""" 全局异常处理模块 ============================================================= 注册 Flask errorhandler,将所有 HTTP 错误和未捕获异常 统一转为 R.failed() JSON 响应,避免前端收到 HTML 错误页导致解析崩溃。 处理范围: - 400:请求参数错误 - 401:未授权 - 403:权限不足 - 404:资源不存在 - 405:请求方法不允许 - 500:服务器内部错误 - Exception:兜底,捕获所有未预期异常 """ import logging import traceback from flask import request from werkzeug.exceptions import HTTPException from utils import R logger = logging.getLogger(__name__) def register_error_handlers(app): """ 注册全局异常处理器 确保所有 HTTP 错误和未捕获异常都返回标准 JSON 响应。 Args: app: Flask 应用实例 """ @app.errorhandler(400) def bad_request(e): return R.failed(msg="请求参数错误", code=400), 400 @app.errorhandler(401) def unauthorized(e): return R.failed(msg="未授权,请重新登录", code=401), 401 @app.errorhandler(403) def forbidden(e): return R.failed(msg="权限不足", code=403), 403 @app.errorhandler(404) def not_found(e): return R.failed(msg="请求的资源不存在", code=404), 404 @app.errorhandler(405) def method_not_allowed(e): return R.failed(msg="请求方法不允许", code=405), 405 @app.errorhandler(500) def internal_error(e): logger.error( f"服务器内部错误, method: {request.method}, path: {request.path}, " f"error: {str(e)}", exc_info=True ) msg = f"服务器内部错误: {str(e)}" if app.debug else "服务器内部错误" return R.failed(msg=msg, code=500), 500 @app.errorhandler(Exception) def handle_exception(e): # HTTPException 子类(如 abort(403))已有专用 handler,不重复处理 if isinstance(e, HTTPException): return e.get_response() # 非HTTP异常:未知运行时异常 logger.error( f"未捕获异常, method: {request.method}, path: {request.path}, " f"error: {traceback.format_exc()}" ) msg = f"服务器内部错误: {str(e)}" if app.debug else "服务器内部错误" return R.failed(msg=msg, code=500), 500 logger.info("全局异常处理器注册成功")