Source code for fabrictools.integrations.ifs.errors

"""IFS API error types."""

from __future__ import annotations

import json
from typing import Any, Optional


class IFSError(Exception):
    """Raised when an IFS HTTP or OData request fails."""

    def __init__(
        self,
        message: str,
        *,
        status_code: Optional[int] = None,
        error_code: Optional[str] = None,
        details: Optional[list[dict[str, Any]]] = None,
        response_body: Optional[str] = None,
    ) -> None:
        super().__init__(message)
        self.status_code = status_code
        self.error_code = error_code
        self.details = details or []
        self.response_body = response_body

[docs] @classmethod def from_http_response(cls, status_code: int, body: str) -> "IFSError": """Build an :class:`IFSError` from an HTTP status and response body.""" parsed = _parse_ifs_error_body(body) message = parsed.get("message") or body or f"IFS request failed with HTTP {status_code}" return cls( message, status_code=status_code, error_code=parsed.get("code"), details=parsed.get("details"), response_body=body, )
def _parse_ifs_error_body(body: str) -> dict[str, Any]: if not body: return {} try: payload = json.loads(body) except json.JSONDecodeError: return {"message": body} if not isinstance(payload, dict): return {"message": body} error = payload.get("error") if isinstance(error, dict): return { "code": error.get("code"), "message": error.get("message"), "details": error.get("details") if isinstance(error.get("details"), list) else [], } if "message" in payload: return { "code": payload.get("code"), "message": payload.get("message"), "details": payload.get("details") if isinstance(payload.get("details"), list) else [], } return {"message": body}