FluxIP/app/core/errors.py

75 lines
2.0 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
from typing import Any
@dataclass(slots=True)
class FieldError:
field: str
message: str
code: str = "INVALID_VALUE"
class AppError(Exception):
def __init__(
self,
detail: str,
*,
code: str = "APPLICATION_ERROR",
status_code: int = 400,
title: str = "请求处理失败",
errors: list[FieldError] | None = None,
context: dict[str, Any] | None = None,
) -> None:
super().__init__(detail)
self.detail = detail
self.code = code
self.status_code = status_code
self.title = title
self.errors = errors or []
self.context = context or {}
class AuthenticationError(AppError):
def __init__(self, detail: str = "请先登录") -> None:
super().__init__(detail, code="AUTHENTICATION_REQUIRED", status_code=401, title="需要登录")
class ConflictError(AppError):
def __init__(self, detail: str, code: str = "RESOURCE_CONFLICT") -> None:
super().__init__(detail, code=code, status_code=409, title="状态冲突")
class ExternalServiceError(AppError):
def __init__(self, detail: str, *, service: str, code: str = "UPSTREAM_ERROR") -> None:
super().__init__(
detail,
code=code,
status_code=502,
title="外部服务异常",
context={"service": service},
)
class NotFoundError(AppError):
def __init__(self, detail: str, code: str = "NOT_FOUND") -> None:
super().__init__(detail, code=code, status_code=404, title="未找到")
class ValidationAppError(AppError):
def __init__(
self,
detail: str,
*,
code: str = "VALIDATION_ERROR",
errors: list[FieldError] | None = None,
) -> None:
super().__init__(
detail,
code=code,
status_code=422,
title="配置校验失败",
errors=errors,
)