52 lines
1.2 KiB
Python
52 lines
1.2 KiB
Python
"""Error envelope standard per tutti i tool MCP."""
|
|
from __future__ import annotations
|
|
|
|
import uuid
|
|
from datetime import UTC, datetime
|
|
from typing import Any
|
|
|
|
|
|
def error_envelope(
|
|
*,
|
|
type_: str,
|
|
code: str,
|
|
message: str,
|
|
retryable: bool,
|
|
suggested_fix: str | None = None,
|
|
details: dict | None = None,
|
|
request_id: str | None = None,
|
|
) -> dict:
|
|
env: dict[str, Any] = {
|
|
"error": {
|
|
"type": type_,
|
|
"code": code,
|
|
"message": message,
|
|
"retryable": retryable,
|
|
},
|
|
"request_id": request_id or uuid.uuid4().hex,
|
|
"data_timestamp": datetime.now(UTC).isoformat(),
|
|
}
|
|
if suggested_fix:
|
|
env["error"]["suggested_fix"] = suggested_fix
|
|
if details:
|
|
env["error"]["details"] = details
|
|
return env
|
|
|
|
|
|
HTTP_CODE_MAP = {
|
|
400: "BAD_REQUEST",
|
|
401: "UNAUTHORIZED",
|
|
403: "FORBIDDEN",
|
|
404: "NOT_FOUND",
|
|
408: "TIMEOUT",
|
|
409: "CONFLICT",
|
|
422: "VALIDATION_ERROR",
|
|
429: "RATE_LIMIT",
|
|
500: "INTERNAL_ERROR",
|
|
502: "UPSTREAM_ERROR",
|
|
503: "UNAVAILABLE",
|
|
504: "GATEWAY_TIMEOUT",
|
|
}
|
|
|
|
RETRYABLE_STATUSES = frozenset({408, 429, 502, 503, 504})
|