ForcePilot/backend/package/yuxi/channel/extensions/gitlab/errors.py
Kris 4a4e256955 feat(gitlab): 新增完整 GitLab 渠道插件支持
实现了 GitLab 全功能集成,包含 Webhook 处理、API 客户端、消息收发、会话管理、安全校验、限流器等完整模块,支持 Issues、Merge Requests、流水线等事件监听与交互。
2026-05-21 10:49:01 +08:00

58 lines
1.5 KiB
Python

from __future__ import annotations
from enum import StrEnum
class GitLabErrorKind(StrEnum):
RETRYABLE = "retryable"
RATE_LIMITED = "rate_limited"
AUTH = "auth"
FORBIDDEN = "forbidden"
NOT_FOUND = "not_found"
DUPLICATE = "duplicate"
VALIDATION = "validation"
NETWORK = "network"
FATAL = "fatal"
def classify_error(status_code: int | None, response_body: dict | None) -> tuple[GitLabErrorKind, str, float | None]:
message = ""
if isinstance(response_body, dict):
message = response_body.get("message", response_body.get("error", ""))
if status_code == 429:
return GitLabErrorKind.RATE_LIMITED, message, 60.0
if status_code == 401:
return GitLabErrorKind.AUTH, message, None
if status_code == 403:
if "duplicate" in message.lower():
return GitLabErrorKind.DUPLICATE, message, None
return GitLabErrorKind.FORBIDDEN, message, None
if status_code == 404:
return GitLabErrorKind.NOT_FOUND, message, None
if status_code == 400 or status_code == 422:
return GitLabErrorKind.VALIDATION, message, None
if status_code and status_code >= 500:
return GitLabErrorKind.RETRYABLE, message, None
if status_code is None:
return GitLabErrorKind.NETWORK, message, None
return GitLabErrorKind.FATAL, message, None
def is_retryable(kind: GitLabErrorKind) -> bool:
return kind in (
GitLabErrorKind.RETRYABLE,
GitLabErrorKind.RATE_LIMITED,
GitLabErrorKind.NETWORK,
)
MAX_RETRIES = 3