Skip to content

Handling Errors

Tutorial

Handling Errors

Understand the exception hierarchy and implement robust error handling

20 min Intermediate
ErrorsExceptionsDebuggingRetry

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 — Parameters
USERNAME = "_FILL_ME_IN_" # Set your email before running
# Cell 2 — Connect
from graph_olap import GraphOLAPClient
client = GraphOLAPClient(username=USERNAME)
# Cell 3 — Provision
from notebook_setup import provision
personas, 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 mapping
try:
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 id
try:
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 instance
try:
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 mappings
mappings = 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 NotFoundError for missing resources and ValidationError for bad input
  • Retry transient errors (ConcurrencyLimitError, ServerError, ServiceUnavailableError) with exponential backoff
  • Catch specific exceptions first, then fall back to GraphOLAPError