ForcePilot/backend/package/yuxi/channel/exceptions.py

72 lines
2.2 KiB
Python
Raw Normal View History

2026-07-15 12:30:58 +08:00
"""多渠道网关异常基类。
插件在投递校验或降级过程中应优先抛出这些异常便于调度器区分
永久失败应停止重试并标记死信与可重试失败应指数退避后重试
"""
from enum import StrEnum
class ChannelErrorClassification(StrEnum):
"""插件对投递异常的分类结果,供调度器决定重试策略。"""
RETRYABLE = "retryable" # 网络抖动、服务端 5xx、未明确分类的瞬态故障
PERMANENT = "permanent" # 配置错误、凭证失效、用户被拉黑、内容永久拒绝
RATE_LIMITED = "rate_limited" # 明确限流,可配合 retry_after 退避
class ChannelError(Exception):
"""渠道网关相关异常的基类。"""
class ChannelPermanentError(ChannelError):
"""渠道侧永久错误,不应重试。
例如凭证失效会话不存在消息内容被渠道永久拒绝用户已拉黑机器人等
"""
class ChannelValidationError(ChannelPermanentError):
"""入站/出站消息格式或签名校验失败。
属于永久失败重复投递无法自动修复
"""
class ChannelRetryableError(ChannelError):
"""渠道侧可重试错误。
例如网络超时渠道服务端 5xx限流429等瞬态故障
"""
class ChannelRateLimitedError(ChannelRetryableError):
"""渠道侧明确限流错误。
可配合 retry_after 进行退避未提供时由调度器使用默认指数退避
"""
def __init__(self, *args: object, retry_after: int | None = None) -> None:
super().__init__(*args)
self.retry_after = retry_after
class ChannelConfigurationError(ChannelPermanentError):
"""渠道配置缺失或非法导致的永久失败。"""
class ChannelNotSupportedError(ChannelPermanentError):
"""当前渠道不支持某种消息类型或能力。"""
class ChannelTransportReconnectRequested(ChannelError):
"""插件请求传输层立即断开并重连。
例如 Slack Socket Mode 收到 disconnect 信封后需要主动断开当前连接
并让生命周期管理器重新建立连接
"""
class ChannelNotLoggedInError(ChannelError):
"""未登录时调用需要登录状态的操作(如发送消息)。"""