zai / app /exceptions /upstream.py
bg5's picture
Upload 85 files
e0b68d2 verified
Raw History Blame Contribute Delete
3.95 kB
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""上游服务异常类。
用于处理上游 API(如 z.ai)返回的错误。
"""
from typing import Any, Dict, Optional
from app.exceptions.base import AppError
class UpstreamError(AppError):
"""上游服务错误基类。
当上游 API 返回错误时抛出。
Attributes:
upstream_code: 上游返回的错误码
upstream_status: 上游返回的 HTTP 状态码
Example:
>>> raise UpstreamError("Upstream API error", upstream_code=50001, upstream_status=500)
"""
def __init__(
self,
message: str,
upstream_code: Optional[int] = None,
upstream_status: Optional[int] = None,
upstream_type: Optional[str] = None,
details: Optional[Dict[str, Any]] = None,
) -> None:
final_details = details or {}
if upstream_code is not None:
final_details["upstream_code"] = upstream_code
if upstream_status is not None:
final_details["upstream_status"] = upstream_status
if upstream_type is not None:
final_details["upstream_type"] = upstream_type
super().__init__(
message=message,
code="upstream_error",
status_code=502, # Bad Gateway
details=final_details,
)
class UpstreamRateLimited(UpstreamError):
"""上游限流异常。
当上游 API 返回 429 状态码时抛出。
Example:
>>> raise UpstreamRateLimited(retry_after=30)
"""
def __init__(
self,
message: str = "Upstream rate limited",
retry_after: Optional[int] = None,
) -> None:
details = {}
if retry_after is not None:
details["retry_after"] = retry_after
super().__init__(
message=message,
upstream_status=429,
details=details,
)
self.code = "rate_limited"
self.status_code = 429
class UpstreamTimeout(UpstreamError):
"""上游超时异常。
当上游 API 响应超时时抛出。
Example:
>>> raise UpstreamTimeout(timeout=30.0)
"""
def __init__(
self,
message: str = "Upstream request timeout",
timeout: Optional[float] = None,
) -> None:
details = {}
if timeout is not None:
details["timeout_seconds"] = timeout
super().__init__(message=message, details=details)
self.code = "upstream_timeout"
self.status_code = 504 # Gateway Timeout
class UpstreamConnectionError(UpstreamError):
"""上游连接失败异常。
当无法连接到上游 API 时抛出。
Example:
>>> raise UpstreamConnectionError("Connection refused")
"""
def __init__(
self,
message: str = "Failed to connect to upstream",
reason: Optional[str] = None,
) -> None:
details = {}
if reason:
details["reason"] = reason
super().__init__(message=message, details=details)
self.code = "upstream_connection_error"
self.status_code = 503 # Service Unavailable
class UpstreamAuthenticationError(UpstreamError):
"""上游认证失败异常。
当上游 Token 失效或无效时抛出。
Example:
>>> raise UpstreamAuthenticationError("Token expired")
"""
def __init__(
self,
message: str = "Upstream authentication failed",
token_hint: Optional[str] = None,
) -> None:
details = {}
if token_hint:
details["token_hint"] = token_hint
super().__init__(
message=message,
upstream_status=401,
details=details,
)
self.code = "upstream_auth_error"
self.status_code = 401