Handling Errors
Tutorial
Handling Errors
Understand the exception hierarchy and implement robust error handling
What You'll Learn
- Exception Hierarchy - Understand GraphOLAPError subtypes
- Common Errors - Handle not-found, validation, and permission errors
- Retry Logic - Implement retry for transient failures
- Debugging - Use error details for troubleshooting
1
Setup
Connect to the platform
# Cell 1 — ParametersUSERNAME = "_FILL_ME_IN_" # Set your email before running# Cell 2 — Connectfrom graph_olap import GraphOLAPClientclient = GraphOLAPClient(username=USERNAME)
# Cell 3 — Provisionfrom notebook_setup import provisionpersonas, conn = provision(USERNAME)analyst = personas["analyst"]admin = personas["admin"]ops = personas["ops"]client = analyst
print(f"Connected | {conn.query_scalar('MATCH (n) RETURN count(n)')} nodes")
2
Exception Hierarchy
GraphOLAPError and its subtypes
from graph_olap.exceptions import ( GraphOLAPError, # base class for all SDK errors PermissionDeniedError, # insufficient permissions NotFoundError, # resource does not exist ValidationError, # invalid request parameters ConflictError, # resource conflict ConcurrencyLimitError, # too many concurrent requests InvalidStateError, # wrong resource state ResourceLockedError, # resource is locked by another operation QueryTimeoutError, # query exceeded time limit AlgorithmTimeoutError, # algorithm exceeded time limit ServerError, # internal server error ServiceUnavailableError, # service temporarily unavailable)
# Hierarchy:# GraphOLAPError# +-- PermissionDeniedError# +-- NotFoundError# +-- ValidationError# +-- ConflictError# | +-- ConcurrencyLimitError# | +-- InvalidStateError# | +-- ResourceLockedError# +-- TimeoutError# | +-- QueryTimeoutError# | +-- AlgorithmTimeoutError# +-- ServerError# +-- ServiceUnavailableError
print("Exception hierarchy loaded successfully")
3
Handling Common Errors
Catch specific exceptions for robust code
# Handle a NotFoundError when fetching a non-existent mappingtry: client.mappings.get(999999)except NotFoundError as e: print(f"NotFoundError: {e}")except GraphOLAPError as e: print(f"SDK error: {e}")
# Handle a ValidationError with an invalid mapping idtry: client.mappings.get(-1)except ValidationError as e: print(f"ValidationError: {e}")except GraphOLAPError as e: print(f"SDK error: {e}")
# Handle a NotFoundError when querying a non-existent graph instancetry: client.instances.get(888888)except NotFoundError as e: print(f"NotFoundError: {e}")except GraphOLAPError as e: print(f"SDK error: {e}")
4
Retry Logic
Handle transient failures with exponential backoff
import time
def with_retry(func, max_retries=3): """Retry a function with exponential backoff for transient errors.""" for attempt in range(max_retries): try: return func() except (ConcurrencyLimitError, ServerError, ServiceUnavailableError) as e: if attempt == max_retries - 1: raise wait = 2 ** attempt print(f"Attempt {attempt + 1} failed: {e}. Retrying in {wait}s...") time.sleep(wait)
# Usage: retry-safe listing of Customer/SHARES_ACCOUNT mappingsmappings = with_retry(lambda: client.mappings.list())print(f"Retrieved {len(mappings)} mappings with retry logic")for m in mappings: print(f" Mapping {m.id}: {m.name}")Key Takeaways
- All SDK errors inherit from
GraphOLAPError-- use it as a catch-all - Use
NotFoundErrorfor missing resources andValidationErrorfor bad input - Retry transient errors (
ConcurrencyLimitError,ServerError,ServiceUnavailableError) with exponential backoff - Catch specific exceptions first, then fall back to
GraphOLAPError