from __future__ import annotations from enum import StrEnum class XmppErrorKind(StrEnum): RETRYABLE = "retryable" AUTH = "auth" FORBIDDEN = "forbidden" NOT_FOUND = "not_found" NOT_ACCEPTABLE = "not_acceptable" REMOTE_SERVER_ERROR = "remote_server_error" SERVICE_UNAVAILABLE = "service_unavailable" RESOURCE_CONSTRAINT = "resource_constraint" RATE_LIMITED = "rate_limited" FATAL = "fatal" def classify_xmpp_error(error_condition: str, error_text: str = "") -> tuple[XmppErrorKind, str, float | None]: condition = (error_condition or "").lower() if condition in ("remote-server-timeout", "remote-server-not-found"): return XmppErrorKind.REMOTE_SERVER_ERROR, f"Remote server error: {error_text}", 5.0 if condition in ("service-unavailable",): return XmppErrorKind.SERVICE_UNAVAILABLE, f"Service unavailable: {error_text}", 30.0 if condition in ("resource-constraint",): return XmppErrorKind.RESOURCE_CONSTRAINT, f"Resource constraint: {error_text}", 10.0 if condition in ("not-authorized", "registration-required"): return XmppErrorKind.AUTH, f"Auth error: {error_text}", None if condition in ("forbidden",): return XmppErrorKind.FORBIDDEN, f"Forbidden: {error_text}", None if condition in ("item-not-found",): return XmppErrorKind.NOT_FOUND, f"Not found: {error_text}", None if condition in ("not-acceptable",): return XmppErrorKind.NOT_ACCEPTABLE, f"Not acceptable: {error_text}", None if condition in ("internal-server-error", "undefined-condition"): return XmppErrorKind.RETRYABLE, f"Server error: {error_text}", 3.0 if condition in ("policy-violation",): return XmppErrorKind.FORBIDDEN, f"Policy violation: {error_text}", None if condition in ("conflict",): return XmppErrorKind.RETRYABLE, f"Conflict: {error_text}", 2.0 if condition in ("gone", "redirect"): return XmppErrorKind.FATAL, f"Permanent failure ({condition}): {error_text}", None return XmppErrorKind.FATAL, f"Unhandled XMPP error ({condition}): {error_text}", None def is_retryable(kind: XmppErrorKind) -> bool: return kind in ( XmppErrorKind.RETRYABLE, XmppErrorKind.SERVICE_UNAVAILABLE, XmppErrorKind.RESOURCE_CONSTRAINT, XmppErrorKind.REMOTE_SERVER_ERROR, XmppErrorKind.RATE_LIMITED, ) MAX_RETRIES = 3