mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-16 01:40:15 +08:00
119 lines
3.8 KiB
Python
119 lines
3.8 KiB
Python
# =============================================================================
|
||
# 新旧对比 - errors.py
|
||
# =============================================================================
|
||
#
|
||
# 【旧版】
|
||
# 旧版 SDK 没有专门的 errors.py 文件。
|
||
# 只有 runtime/rpc/jsonrpc.py 中定义了 JSONRPCErrorData 用于内部通信。
|
||
#
|
||
# 【新版】
|
||
# 新增 errors.py,定义统一的 AstrBotError 异常类:
|
||
# - 包含 code, message, hint, retryable 字段
|
||
# - 提供工厂方法: cancelled(), capability_not_found(), invalid_input(),
|
||
# protocol_version_mismatch(), protocol_error(), internal_error()
|
||
# - 支持序列化/反序列化: to_payload(), from_payload()
|
||
#
|
||
# 【设计目的】
|
||
# 新版采用分布式架构,插件与核心通过 RPC 通信。
|
||
# AstrBotError 提供统一的错误表示,便于跨进程传递错误信息。
|
||
#
|
||
# =============================================================================
|
||
# TODO: 功能缺失
|
||
# =============================================================================
|
||
#
|
||
# 1. 缺少旧版异常类兼容
|
||
# - 如果旧版有其他异常类(如 ChatProviderNotFoundError),需要考虑兼容
|
||
# - 当前 AstrBotError 可覆盖大部分场景
|
||
#
|
||
# 2. 缺少错误码常量定义
|
||
# - 建议添加错误码枚举或常量,便于错误匹配
|
||
# - 例如: ERROR_CODE_CANCELLED = "cancelled"
|
||
#
|
||
# =============================================================================
|
||
|
||
from __future__ import annotations
|
||
|
||
from dataclasses import dataclass
|
||
|
||
|
||
@dataclass(slots=True)
|
||
class AstrBotError(Exception):
|
||
code: str
|
||
message: str
|
||
hint: str = ""
|
||
retryable: bool = False
|
||
|
||
def __str__(self) -> str:
|
||
return self.message
|
||
|
||
@classmethod
|
||
def cancelled(cls, message: str = "调用被取消") -> "AstrBotError":
|
||
return cls(
|
||
code="cancelled",
|
||
message=message,
|
||
hint="",
|
||
retryable=False,
|
||
)
|
||
|
||
@classmethod
|
||
def capability_not_found(cls, name: str) -> "AstrBotError":
|
||
return cls(
|
||
code="capability_not_found",
|
||
message=f"未找到能力:{name}",
|
||
hint="请确认 AstrBot Core 是否已注册该 capability",
|
||
retryable=False,
|
||
)
|
||
|
||
@classmethod
|
||
def invalid_input(cls, message: str) -> "AstrBotError":
|
||
return cls(
|
||
code="invalid_input",
|
||
message=message,
|
||
hint="请检查调用参数",
|
||
retryable=False,
|
||
)
|
||
|
||
@classmethod
|
||
def protocol_version_mismatch(cls, message: str) -> "AstrBotError":
|
||
return cls(
|
||
code="protocol_version_mismatch",
|
||
message=message,
|
||
hint="请升级 astrbot_sdk 至最新版本",
|
||
retryable=False,
|
||
)
|
||
|
||
@classmethod
|
||
def protocol_error(cls, message: str) -> "AstrBotError":
|
||
return cls(
|
||
code="protocol_error",
|
||
message=message,
|
||
hint="请检查通信双方的协议实现",
|
||
retryable=False,
|
||
)
|
||
|
||
@classmethod
|
||
def internal_error(cls, message: str) -> "AstrBotError":
|
||
return cls(
|
||
code="internal_error",
|
||
message=message,
|
||
hint="请联系插件作者",
|
||
retryable=False,
|
||
)
|
||
|
||
def to_payload(self) -> dict[str, object]:
|
||
return {
|
||
"code": self.code,
|
||
"message": self.message,
|
||
"hint": self.hint,
|
||
"retryable": self.retryable,
|
||
}
|
||
|
||
@classmethod
|
||
def from_payload(cls, payload: dict[str, object]) -> "AstrBotError":
|
||
return cls(
|
||
code=str(payload.get("code", "unknown_error")),
|
||
message=str(payload.get("message", "未知错误")),
|
||
hint=str(payload.get("hint", "")),
|
||
retryable=bool(payload.get("retryable", False)),
|
||
)
|