""" 统一用户友好错误提示规范 遵循技术方案文档要求,对外返回简洁、明确、可执行的用户提示信息 """ from typing import Optional, Dict, Any from enum import Enum class ErrorCode(Enum): """业务错误码 - 与HTTP状态码语义一致""" SUCCESS = 200 BAD_REQUEST = 400 # 请求参数/格式错误 UNAUTHORIZED = 401 # 认证失败 FORBIDDEN = 403 # 权限/业务拒绝 NOT_FOUND = 404 # 资源不存在 SERVER_ERROR = 500 # 系统异常 class UserFriendlyError(Exception): """用户友好错误异常 特点: - 对外返回简洁、明确、可执行的用户提示信息 - 内部记录完整异常堆栈以便排查 - 不暴露内部实现细节 """ def __init__( self, code: int, message: str, user_message: Optional[str] = None, details: Optional[Dict[str, Any]] = None, log_level: str = "error" ): """ Args: code: 业务错误码 message: 内部错误信息(用于日志) user_message: 用户友好提示(可执行的操作) details: 额外详情(用于调试,不返回给用户) log_level: 日志级别 (debug/info/warning/error) """ self.code = code self.message = message self.user_message = user_message or self._get_default_user_message(code, message) self.details = details or {} self.log_level = log_level def _get_default_user_message(self, code: int, message: str) -> str: """获取默认用户友好提示""" # 根据常见错误类型返回友好提示 if "用户名" in message and "密码" in message: return "用户名或密码错误,请检查后重试。" elif "密码错误" in message: return "用户名或密码错误,请检查后重试。" elif "用户名" in message: return "用户名不存在,请检查后重试。" elif "会话" in message or "登录" in message: return "会话已过期,请重新登录。" elif "卡密" in message and ("过期" in message or "到期" in message): return "您的卡密已到期,请前往续费或联系客户支持。" elif "卡密" in message: return "卡密无效,请检查后重试。" elif "设备" in message or "机器" in message: return "账号已在其他设备登录,如非本人操作请联系客服。" elif "禁用" in message or "封禁" in message: return "账号已被禁用,请联系管理员或客服。" elif "参数" in message or "请求" in message: return "请求参数错误,请检查后重试。" elif "签名" in message: return "请求验证失败,请稍后重试。" elif "系统" in message or "服务" in message or "异常" in message: return "系统异常,请稍后重试;若持续发生请联系客服。" else: return "操作失败,请稍后重试。" def to_dict(self) -> Dict[str, Any]: """转换为响应字典""" return { "code": self.code, "msg": self.user_message, "data": None } def __str__(self): return f"[{self.code}] {self.message} -> 用户提示: {self.user_message}" def create_client_response( code: int = 200, msg: str = "成功", data: Any = None ) -> Dict[str, Any]: """ 创建统一客户端响应格式 Args: code: 业务码 msg: 用户提示信息 data: 响应数据 Returns: 格式化的响应字典 """ return { "code": code, "msg": msg, "data": data } # ============ 常用错误工厂函数 ============ def error_bad_request(message: str = "请求参数错误,请检查后重试") -> UserFriendlyError: """400 - 请求参数/格式错误""" return UserFriendlyError( code=ErrorCode.BAD_REQUEST.value, message=message, user_message=message ) def error_unauthorized(message: str = "认证失败") -> UserFriendlyError: """401 - 认证失败""" if "用户名" in message or "密码" in message: user_msg = "用户名或密码错误,请检查后重试。" elif "会话" in message or "过期" in message: user_msg = "会话已过期,请重新登录。" else: user_msg = "会话验证失败,请重新登录。" return UserFriendlyError( code=ErrorCode.UNAUTHORIZED.value, message=message, user_message=user_msg ) def error_forbidden(message: str = "权限拒绝") -> UserFriendlyError: """403 - 权限/业务拒绝""" # 根据消息内容返回不同的用户友好提示 if "卡密" in message and ("过期" in message or "到期" in message): user_msg = "您的卡密已到期,请前往续费或联系客户支持。" elif "卡密" in message: user_msg = "卡密无效,请检查后重试。" elif "设备" in message or "机器" in message: user_msg = "该账号已绑定其他设备。如需切换设备请先解绑或联系客服。" elif "禁用" in message or "封禁" in message: user_msg = "账号已被禁用,请联系管理员或客服。" else: user_msg = message return UserFriendlyError( code=ErrorCode.FORBIDDEN.value, message=message, user_message=user_msg ) def error_not_found(message: str = "资源未找到") -> UserFriendlyError: """404 - 资源不存在""" return UserFriendlyError( code=ErrorCode.NOT_FOUND.value, message=message, user_message=message ) def error_server_error(message: str = "系统异常") -> UserFriendlyError: """500 - 系统异常""" return UserFriendlyError( code=ErrorCode.SERVER_ERROR.value, message=message, user_message="系统异常,请稍后重试;若持续发生请联系客服。" )