File size: 3,214 Bytes
b4f2238
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
"""
LLM 专用异常模块

定义 LLM 模块特有的异常类型,继承自 apps.core.exceptions.

Requirements: 1.3, 1.4, 1.5, 1.6
"""

from typing import Any

from apps.core.exceptions import APIError, AuthenticationError, ExternalServiceError, NetworkError


class LLMError(ExternalServiceError):
    """
    LLM 错误基类

    所有 LLM 相关异常的基类.

    HTTP 状态码:502
    """

    def __init__(
        self, message: str = "LLM 服务错误", code: str | None = None, errors: dict[str, Any] | None = None
    ) -> None:
        super().__init__(message=message, code=code or "LLM_ERROR", errors=errors)


class LLMNetworkError(LLMError, NetworkError):
    """
    LLM 网络错误

    使用场景:
    - 网络连接失败
    - 连接被拒绝
    - DNS 解析失败

    HTTP 状态码:502
    """

    def __init__(
        self, message: str = "LLM 网络连接失败", code: str | None = None, errors: dict[str, Any] | None = None
    ) -> None:
        super().__init__(message=message, code=code or "LLM_NETWORK_ERROR", errors=errors)


class LLMAPIError(LLMError, APIError):
    """
    LLM API 错误

    使用场景:
    - API 返回错误状态码
    - API 响应格式错误
    - API 业务逻辑错误

    HTTP 状态码:502
    """

    def __init__(
        self,
        message: str = "LLM API 调用错误",
        code: str | None = None,
        errors: dict[str, Any] | None = None,
        status_code: int | None = None,
    ) -> None:
        if status_code is not None:
            errors = errors or {}
            errors["status_code"] = status_code
        super().__init__(message=message, code=code or "LLM_API_ERROR", errors=errors)
        self.status_code = status_code


class LLMAuthenticationError(LLMError, AuthenticationError):
    """
    LLM 认证错误

    使用场景:
    - API Key 无效
    - API Key 缺失
    - API Key 过期

    HTTP 状态码:401
    """

    def __init__(
        self,
        message: str = "SiliconFlow API Key 无效或缺失",
        code: str | None = None,
        errors: dict[str, Any] | None = None,
    ) -> None:
        super().__init__(
            message=message,
            code=code or "LLM_AUTH_ERROR",
            errors=errors or {"api_key": "请检查 SILICONFLOW.API_KEY 配置"},
        )


class LLMBackendUnavailableError(LLMAPIError):
    def __init__(self, message: str = "所有 LLM 后端均不可用", errors: dict[str, Any] | None = None) -> None:
        super().__init__(message=message, code="LLM_ALL_BACKENDS_UNAVAILABLE", errors=errors)


class LLMTimeoutError(LLMError):
    """
    LLM 超时错误

    使用场景:
    - 请求超时
    - 响应超时

    HTTP 状态码:504
    """

    def __init__(
        self,
        message: str = "LLM 请求超时",
        code: str | None = None,
        errors: dict[str, Any] | None = None,
        timeout_seconds: float | None = None,
    ) -> None:
        if timeout_seconds is not None:
            errors = errors or {}
            errors["timeout_seconds"] = timeout_seconds
        super().__init__(message=message, code=code or "LLM_TIMEOUT", errors=errors)
        self.timeout_seconds = timeout_seconds