ForcePilot/backend/package/yuxi/channel/extensions/feishu/errors.py

58 lines
1.8 KiB
Python
Raw Normal View History

from __future__ import annotations
from enum import StrEnum
class FeishuErrorCategory(StrEnum):
RATE_LIMIT = "rate_limit"
AUTH = "auth"
TRANSIENT = "transient"
PERMANENT = "permanent"
NOT_FOUND = "not_found"
VALIDATION = "validation"
class FeishuError(Exception):
def __init__(self, message: str, *, code: int = 0, category: str = "transient"):
super().__init__(message)
self.code = code
self.category = category
class FeishuAuthError(FeishuError):
def __init__(self, message: str, *, code: int = 0):
super().__init__(message, code=code, category="auth")
class FeishuRateLimitError(FeishuError):
def __init__(self, message: str = "Rate limited", *, code: int = 99991400):
super().__init__(message, code=code, category="rate_limit")
class FeishuConnectionError(FeishuError):
def __init__(self, message: str, *, code: int = 0):
super().__init__(message, code=code, category="transient")
def classify_feishu_error(code: int, msg: str = "") -> FeishuError:
if code in (99991400,):
return FeishuRateLimitError(msg or "Rate limited", code=code)
if code in (99991403,):
return FeishuRateLimitError(msg or "Quota exceeded", code=code)
if code in (99991663, 99991664, 99991665):
return FeishuAuthError(msg or "Authentication failed", code=code)
if code in (230011, 231003):
return FeishuError(msg or "Reply target not found", code=code, category="transient")
if code in (0,):
return FeishuError(msg, code=code, category="transient")
return FeishuError(msg or f"Feishu API error {code}", code=code, category="permanent")
RETRYABLE_CODES = frozenset({
99991400, 99991403,
230011, 231003,
})
AUTH_ERROR_CODES = frozenset({
99991663, 99991664, 99991665,
})