Exceptions ========== All SDK exceptions inherit from :class:`~coreplexml.exceptions.CorePlexMLError`. Each exception carries three attributes that provide structured error information from the server. Exception Hierarchy ------------------- :: CorePlexMLError +-- AuthenticationError (HTTP 401 / 403) +-- NotFoundError (HTTP 404) +-- ValidationError (HTTP 422) Autodoc Reference ----------------- .. automodule:: coreplexml.exceptions :members: :undoc-members: :show-inheritance: CorePlexMLError --------------- .. code-block:: python class CorePlexMLError(Exception): message: str # Human-readable error message status_code: int | None # HTTP status code (if applicable) detail: str | None # Detailed error info from the server Base exception for all CorePlexML SDK errors. Raised for any HTTP status code >= 400 that does not map to a more specific subclass. AuthenticationError ------------------- Raised when the server returns HTTP **401** (Unauthorized) or **403** (Forbidden). This typically means the API key is missing, invalid, or expired. .. code-block:: python from coreplexml import CorePlexMLClient, AuthenticationError client = CorePlexMLClient( base_url="https://ml.example.com", api_key="invalid-key", ) try: client.projects.list() except AuthenticationError as e: print(f"Authentication failed (HTTP {e.status_code}): {e.detail}") # Prompt the user to check their API key NotFoundError ------------- Raised when the server returns HTTP **404**. The requested resource (project, dataset, model, etc.) does not exist or is not accessible to the current user. .. code-block:: python from coreplexml import CorePlexMLClient, NotFoundError try: client.projects.get("00000000-0000-0000-0000-000000000000") except NotFoundError as e: print(f"Resource not found: {e.detail}") ValidationError --------------- Raised when the server returns HTTP **422** (Unprocessable Entity). The request body or parameters did not pass server-side validation -- for example, an empty project name or an invalid column reference. .. code-block:: python from coreplexml import CorePlexMLClient, ValidationError try: client.projects.create("") # empty name except ValidationError as e: print(f"Validation failed: {e.detail}") Error Handling Patterns ----------------------- Catch-All Pattern ^^^^^^^^^^^^^^^^^ Handle all SDK errors with a single except clause: .. code-block:: python from coreplexml import CorePlexMLError try: result = client.experiments.create( project_id=project_id, dataset_version_id=version_id, target_column="target", problem_type="classification", ) except CorePlexMLError as e: print(f"API error ({e.status_code}): {e.message}") Granular Pattern ^^^^^^^^^^^^^^^^ Handle each error type differently: .. code-block:: python from coreplexml import ( CorePlexMLError, AuthenticationError, NotFoundError, ValidationError, ) try: model = client.models.get(model_id) prediction = client.models.predict(model_id, {"feature": 1.0}) except AuthenticationError: print("API key is invalid or expired. Regenerate it in Settings > API Keys.") except NotFoundError: print(f"Model {model_id} does not exist or was deleted.") except ValidationError as e: print(f"Invalid input: {e.detail}") except CorePlexMLError as e: print(f"Unexpected error ({e.status_code}): {e.message}") Retry Pattern ^^^^^^^^^^^^^ Retry transient errors (5xx) with exponential backoff: .. code-block:: python import time from coreplexml import CorePlexMLError def predict_with_retry(client, deployment_id, inputs, max_retries=3): """Make a prediction with automatic retry on server errors.""" for attempt in range(max_retries): try: return client.deployments.predict(deployment_id, inputs) except CorePlexMLError as e: if e.status_code and e.status_code >= 500 and attempt < max_retries - 1: wait = 2 ** attempt # 1s, 2s, 4s print(f"Server error, retrying in {wait}s...") time.sleep(wait) else: raise result = predict_with_retry(client, deployment_id, {"feature": 1.0}) Timeout Handling ^^^^^^^^^^^^^^^^ Handle polling timeouts for long-running jobs: .. code-block:: python from coreplexml import CorePlexMLError try: result = client.experiments.wait( experiment_id, interval=10.0, timeout=7200.0, # 2 hours ) except CorePlexMLError as e: if "timed out" in str(e): print("Experiment is still running. Check back later:") status = client.experiments.get(experiment_id) print(f" Current status: {status.get('status')}") else: raise