- 新增jd模块基础路由,整合app_store和payment子路由 - 实现苹果权益充值接口,支持苹果、携程及沃尔玛多个渠道 - 实现卡号密码查询接口,支持不同类别订单查询 - 新增短信认证相关接口,实现短信验证码发送及短信登录 - 新增商品管理接口,支持SKU详情查询及账号类下单功能 - 新增订单管理接口,实现订单删除功能 - 实现支付相关接口,增加刷新支付参数功能 - 定义完整请求及响应数据模型,确保接口数据规范 - 编写AppStoreSpider类,封装苹果应用内订单处理逻辑 - 引入多种代理池及请求重试机制,增强接口稳定性 - 添加详细日志记录,便于请求追踪与错误排查
247 lines
5.8 KiB
Python
247 lines
5.8 KiB
Python
"""
|
|
Custom exception hierarchy for application errors.
|
|
Maps exceptions to HTTP status codes and business codes.
|
|
"""
|
|
|
|
from typing import Optional, Any
|
|
from core.responses import BusinessCode
|
|
|
|
|
|
class BaseAppException(Exception):
|
|
"""
|
|
Base exception for all application exceptions.
|
|
|
|
Attributes:
|
|
message: Error message
|
|
code: Business error code
|
|
status_code: HTTP status code
|
|
details: Additional error details
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str,
|
|
code: BusinessCode = BusinessCode.UNKNOWN_ERROR,
|
|
status_code: int = 500,
|
|
details: Optional[dict[str, Any]] = None,
|
|
):
|
|
self.message = message
|
|
self.code = code
|
|
self.status_code = status_code
|
|
self.details = details or {}
|
|
super().__init__(self.message)
|
|
|
|
|
|
class ValidationException(BaseAppException):
|
|
"""
|
|
Exception for validation errors.
|
|
|
|
HTTP Status: 400 Bad Request
|
|
Business Code Range: 3000-3999
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str,
|
|
code: BusinessCode = BusinessCode.INVALID_INPUT,
|
|
details: Optional[dict[str, Any]] = None,
|
|
):
|
|
super().__init__(message=message, code=code, status_code=400, details=details)
|
|
|
|
|
|
class NotFoundException(BaseAppException):
|
|
"""
|
|
Exception for resource not found errors.
|
|
|
|
HTTP Status: 404 Not Found
|
|
Business Code: 4001
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str,
|
|
resource: str = "Resource",
|
|
details: Optional[dict[str, Any]] = None,
|
|
):
|
|
super().__init__(
|
|
message=message or f"{resource} not found",
|
|
code=BusinessCode.RESOURCE_NOT_FOUND,
|
|
status_code=404,
|
|
details=details,
|
|
)
|
|
|
|
|
|
class ConflictException(BaseAppException):
|
|
"""
|
|
Exception for resource conflict errors.
|
|
|
|
HTTP Status: 409 Conflict
|
|
Business Code: 4003
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str,
|
|
code: BusinessCode = BusinessCode.RESOURCE_CONFLICT,
|
|
details: Optional[dict[str, Any]] = None,
|
|
):
|
|
super().__init__(message=message, code=code, status_code=409, details=details)
|
|
|
|
|
|
class AlreadyExistsException(BaseAppException):
|
|
"""
|
|
Exception for resource already exists errors.
|
|
|
|
HTTP Status: 409 Conflict
|
|
Business Code: 4002
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str,
|
|
resource: str = "Resource",
|
|
details: Optional[dict[str, Any]] = None,
|
|
):
|
|
super().__init__(
|
|
message=message or f"{resource} already exists",
|
|
code=BusinessCode.RESOURCE_ALREADY_EXISTS,
|
|
status_code=409,
|
|
details=details,
|
|
)
|
|
|
|
|
|
class AuthenticationException(BaseAppException):
|
|
"""
|
|
Exception for authentication errors.
|
|
|
|
HTTP Status: 401 Unauthorized
|
|
Business Code Range: 1001-1099
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str,
|
|
code: BusinessCode = BusinessCode.LOGIN_FAILED,
|
|
details: Optional[dict[str, Any]] = None,
|
|
):
|
|
super().__init__(message=message, code=code, status_code=401, details=details)
|
|
|
|
|
|
class PermissionException(BaseAppException):
|
|
"""
|
|
Exception for permission/authorization errors.
|
|
|
|
HTTP Status: 403 Forbidden
|
|
Business Code: 1003
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str,
|
|
code: BusinessCode = BusinessCode.INSUFFICIENT_PERMISSIONS,
|
|
details: Optional[dict[str, Any]] = None,
|
|
):
|
|
super().__init__(message=message, code=code, status_code=403, details=details)
|
|
|
|
|
|
class BusinessLogicException(BaseAppException):
|
|
"""
|
|
Exception for business logic errors.
|
|
|
|
HTTP Status: 400 Bad Request
|
|
Business Code Range: 2000-2999
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str,
|
|
code: BusinessCode = BusinessCode.OPERATION_NOT_ALLOWED,
|
|
details: Optional[dict[str, Any]] = None,
|
|
):
|
|
super().__init__(message=message, code=code, status_code=400, details=details)
|
|
|
|
|
|
class DatabaseException(BaseAppException):
|
|
"""
|
|
Exception for database errors.
|
|
|
|
HTTP Status: 503 Service Unavailable
|
|
Business Code: 5001
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str = "Database error occurred",
|
|
details: Optional[dict[str, Any]] = None,
|
|
):
|
|
super().__init__(
|
|
message=message,
|
|
code=BusinessCode.DATABASE_ERROR,
|
|
status_code=503,
|
|
details=details,
|
|
)
|
|
|
|
|
|
class CacheException(BaseAppException):
|
|
"""
|
|
Exception for cache/Redis errors.
|
|
|
|
HTTP Status: 503 Service Unavailable
|
|
Business Code: 5003
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str = "Cache service error",
|
|
details: Optional[dict[str, Any]] = None,
|
|
):
|
|
super().__init__(
|
|
message=message,
|
|
code=BusinessCode.CACHE_ERROR,
|
|
status_code=503,
|
|
details=details,
|
|
)
|
|
|
|
|
|
class ExternalServiceException(BaseAppException):
|
|
"""
|
|
Exception for external service errors.
|
|
|
|
HTTP Status: 502 Bad Gateway
|
|
Business Code: 5002
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
message: str = "External service unavailable",
|
|
details: Optional[dict[str, Any]] = None,
|
|
):
|
|
super().__init__(
|
|
message=message,
|
|
code=BusinessCode.EXTERNAL_SERVICE_ERROR,
|
|
status_code=502,
|
|
details=details,
|
|
)
|
|
|
|
|
|
class JDServiceException(BaseAppException):
|
|
"""
|
|
Exception for external service errors.
|
|
|
|
HTTP Status: 502 Bad Gateway
|
|
Business Code: 5002
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
code: BusinessCode = BusinessCode.NOT_IMPLEMENTED,
|
|
message: str = "External service unavailable",
|
|
details: Optional[dict[str, Any]] = None,
|
|
):
|
|
super().__init__(
|
|
message=message,
|
|
code=code,
|
|
status_code=200,
|
|
details=details,
|
|
)
|