99520c69d7
1.新增后端测试 2.增加了后端的加密 3.增加了i18n(国际化)
145 lines
4.3 KiB
Python
145 lines
4.3 KiB
Python
# Copyright 2026 zhaoxi826
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
"""KiloStar 统一异常体系。
|
|
|
|
设计原则:所有自定义异常归到两条主轴下。
|
|
|
|
- ``BusinessError``:业务可预期错误,HTTP 层映射 4xx;前端可读、可展示给用户。
|
|
- ``InfraError``:系统/基础设施失败错误,HTTP 层映射 5xx;通常需要落日志告警。
|
|
其下再细分为 ``RetryableError``(瞬时故障,可由 ``retry_on_retryable_error`` 自动重试)
|
|
与 ``NonRetryableError``(确定性失败,重试无意义)。
|
|
|
|
注意:用 ``InfraError`` 而非 ``SystemError`` 是为了避免与 Python 内置的
|
|
``SystemError`` 冲突。
|
|
|
|
每个异常类都带 ``http_status`` 与 ``code`` 类属性,``api/__init__.py`` 的统一
|
|
handler 根据它们直接生成结构化响应,避免业务代码里硬编码状态码。
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
class KiloStarError(Exception):
|
|
"""KiloStar 所有自定义异常的总根。"""
|
|
|
|
http_status: int = 500
|
|
code: str = "kilostar_error"
|
|
|
|
|
|
# ─── 主轴 1:业务可预期错误(4xx) ───────────────────────────────────────────
|
|
|
|
|
|
class BusinessError(KiloStarError):
|
|
"""业务层可预期错误的基类,HTTP 层默认 400。"""
|
|
|
|
http_status = 400
|
|
code = "business_error"
|
|
|
|
|
|
class DemandError(BusinessError):
|
|
"""需求/任务参数不合法或不满足前置条件时抛出。"""
|
|
|
|
http_status = 400
|
|
code = "demand_error"
|
|
|
|
|
|
# 用户域 ─────────────────────────────────────────
|
|
|
|
|
|
class UserError(BusinessError):
|
|
"""用户域错误的基类。"""
|
|
|
|
http_status = 400
|
|
code = "user_error"
|
|
|
|
|
|
class UserNotExistError(UserError):
|
|
"""按用户名/ID 查询时用户不存在。"""
|
|
|
|
http_status = 404
|
|
code = "user_not_exist"
|
|
|
|
|
|
class UserPasswordError(UserError):
|
|
"""口令校验失败(旧密码错误、登录密码错误等)。"""
|
|
|
|
http_status = 401
|
|
code = "user_password_error"
|
|
|
|
|
|
# Provider 域 ─────────────────────────────────────
|
|
|
|
|
|
class ProviderError(BusinessError):
|
|
"""模型 Provider 域错误的基类。"""
|
|
|
|
http_status = 400
|
|
code = "provider_error"
|
|
|
|
|
|
class ProviderNotExistError(ProviderError):
|
|
"""请求了一个未注册的 Provider 时抛出。"""
|
|
|
|
http_status = 404
|
|
code = "provider_not_exist"
|
|
|
|
|
|
class ModelNotExistError(BusinessError):
|
|
"""请求了一个未在 Provider 中注册的模型 ID 时抛出。"""
|
|
|
|
http_status = 404
|
|
code = "model_not_exist"
|
|
|
|
|
|
# Workflow 域 ─────────────────────────────────────
|
|
|
|
|
|
class WorkflowExit(BusinessError):
|
|
"""工作流被显式终止(用户取消、上游决策跳出等),是预期内的退出信号。"""
|
|
|
|
http_status = 400
|
|
code = "workflow_exit"
|
|
|
|
|
|
# ─── 主轴 2:系统/基础设施失败错误(5xx) ────────────────────────────────────
|
|
|
|
|
|
class InfraError(KiloStarError):
|
|
"""系统/基础设施失败错误的基类,HTTP 层默认 500。"""
|
|
|
|
http_status = 500
|
|
code = "infra_error"
|
|
|
|
|
|
class RetryableError(InfraError):
|
|
"""瞬时故障(如网络抖动),可由 ``retry_on_retryable_error`` 自动重试。"""
|
|
|
|
http_status = 503
|
|
code = "retryable_error"
|
|
|
|
|
|
class NonRetryableError(InfraError):
|
|
"""确定性的系统失败,重试无意义。"""
|
|
|
|
http_status = 500
|
|
code = "non_retryable_error"
|
|
|
|
|
|
class WorkflowError(InfraError):
|
|
"""工作流执行期错误的基类,HTTP 层映射为 5xx。"""
|
|
|
|
http_status = 500
|
|
code = "workflow_error"
|