Files
AstrBot/src-new/astrbot_sdk/errors.py

119 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# =============================================================================
# 新旧对比 - 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)),
)