实现了 GitLab 全功能集成,包含 Webhook 处理、API 客户端、消息收发、会话管理、安全校验、限流器等完整模块,支持 Issues、Merge Requests、流水线等事件监听与交互。
58 lines
1.5 KiB
Python
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
|