53 lines
1.5 KiB
Python
53 lines
1.5 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from enum import StrEnum
|
||
|
|
|
||
|
|
from yuxi.channels.exceptions import (
|
||
|
|
ChannelAuthenticationError,
|
||
|
|
ChannelException,
|
||
|
|
ChannelNotConnectedError,
|
||
|
|
ChannelRateLimitError,
|
||
|
|
ChannelTimeoutError,
|
||
|
|
MessageTooLargeError,
|
||
|
|
TokenExpiredError,
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
class ErrorCategory(StrEnum):
|
||
|
|
TRANSIENT = "transient"
|
||
|
|
PERMANENT = "permanent"
|
||
|
|
RATE_LIMIT = "rate_limit"
|
||
|
|
AUTH_EXPIRED = "auth_expired"
|
||
|
|
CIRCUIT_OPEN = "circuit_open"
|
||
|
|
TIMEOUT = "timeout"
|
||
|
|
|
||
|
|
|
||
|
|
_ERROR_CATEGORY_MAP: dict[type[Exception], ErrorCategory] = {
|
||
|
|
ChannelNotConnectedError: ErrorCategory.TRANSIENT,
|
||
|
|
ChannelRateLimitError: ErrorCategory.RATE_LIMIT,
|
||
|
|
TokenExpiredError: ErrorCategory.AUTH_EXPIRED,
|
||
|
|
ChannelAuthenticationError: ErrorCategory.PERMANENT,
|
||
|
|
ChannelTimeoutError: ErrorCategory.TIMEOUT,
|
||
|
|
MessageTooLargeError: ErrorCategory.PERMANENT,
|
||
|
|
TimeoutError: ErrorCategory.TIMEOUT,
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
def classify_error(error: Exception) -> ErrorCategory:
|
||
|
|
error_type = type(error)
|
||
|
|
if error_type in _ERROR_CATEGORY_MAP:
|
||
|
|
return _ERROR_CATEGORY_MAP[error_type]
|
||
|
|
|
||
|
|
try:
|
||
|
|
from yuxi.channels.infra.circuit_breaker import CircuitBreakerOpenError
|
||
|
|
|
||
|
|
if isinstance(error, CircuitBreakerOpenError):
|
||
|
|
return ErrorCategory.CIRCUIT_OPEN
|
||
|
|
except ImportError:
|
||
|
|
pass
|
||
|
|
|
||
|
|
if isinstance(error, ChannelException):
|
||
|
|
return ErrorCategory.TRANSIENT if error.retryable else ErrorCategory.PERMANENT
|
||
|
|
|
||
|
|
return ErrorCategory.TRANSIENT
|