File size: 3,498 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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
"""
通用业务异常类
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from django.utils.functional import Promise

from .base import BusinessException

__all__: list[str] = [
    "ValidationException",
    "PermissionDenied",
    "NotFoundError",
    "ConflictError",
    "AuthenticationError",
    "RateLimitError",
    "ForbiddenError",
    "UnauthorizedError",
]


class ValidationException(BusinessException):
    """
    验证异常

    使用场景:
    - 数据格式不正确
    - 业务规则验证失败
    - 字段值不符合要求

    HTTP 状态码:400
    """

    def __init__(
        self, message: str | Promise = "数据验证失败", code: str | None = None, errors: dict[str, Any] | None = None
    ) -> None:
        super().__init__(message=message, code=code or "VALIDATION_ERROR", errors=errors)


class PermissionDenied(BusinessException):
    """
    权限拒绝异常

    使用场景:
    - 用户无权限执行操作
    - 访问被拒绝的资源

    HTTP 状态码:403
    """

    def __init__(
        self, message: str | Promise = "无权限执行该操作", code: str | None = None, errors: dict[str, Any] | None = None
    ) -> None:
        super().__init__(message=message, code=code or "PERMISSION_DENIED", errors=errors)


class NotFoundError(BusinessException):
    """
    资源不存在异常

    使用场景:
    - 查询的资源不存在
    - ID 无效

    HTTP 状态码:404
    """

    def __init__(
        self, message: str | Promise = "资源不存在", code: str | None = None, errors: dict[str, Any] | None = None
    ) -> None:
        super().__init__(message=message, code=code or "NOT_FOUND", errors=errors)


class ConflictError(BusinessException):
    """
    资源冲突异常

    使用场景:
    - 资源已存在(重复创建)
    - 资源状态冲突
    - 并发修改冲突

    HTTP 状态码:409
    """

    def __init__(
        self, message: str | Promise = "资源冲突", code: str | None = None, errors: dict[str, Any] | None = None
    ) -> None:
        super().__init__(message=message, code=code or "CONFLICT", errors=errors)


class AuthenticationError(BusinessException):
    """
    认证失败异常

    使用场景:
    - 登录失败
    - Token 无效
    - 会话过期

    HTTP 状态码:401
    """

    def __init__(
        self, message: str | Promise = "认证失败", code: str | None = None, errors: dict[str, Any] | None = None
    ) -> None:
        super().__init__(message=message, code=code or "AUTHENTICATION_ERROR", errors=errors)


class RateLimitError(BusinessException):
    """
    频率限制异常

    使用场景:
    - 请求过于频繁
    - 超过配额限制

    HTTP 状态码:429
    """

    def __init__(
        self, message: str | Promise = "请求过于频繁", code: str | None = None, errors: dict[str, Any] | None = None
    ) -> None:
        super().__init__(message=message, code=code or "RATE_LIMIT_ERROR", errors=errors)


# 向后兼容的别名
class ForbiddenError(PermissionDenied):
    """无权限访问(向后兼容)"""

    def __init__(self, message: str | Promise = "无权限访问") -> None:
        super().__init__(message)
        self.status = 403


class UnauthorizedError(AuthenticationError):
    """未认证(向后兼容)"""

    def __init__(self, message: str | Promise = "请先登录") -> None:
        super().__init__(message)
        self.status = 401