Intermediate20 min

Errors and exceptions

Read tracebacks, catch what you can handle, and fail loudly on everything else.

Why this matters in AI / ML / GenAI

LLM APIs time out, rate-limit, and return malformed JSON. GPUs run out of memory. Files go missing mid-pipeline. Retrying the right exceptions — and not swallowing the rest — is the difference between a resilient service and a silent data-corruption incident.

Reading a traceback

Read tracebacks bottom-up. The last line is the exception type and message; the lines above are the call stack, most recent last.

Types you will meet constantly:

  • KeyError — dict key missing (bad API response shape)
  • TypeError — wrong type (a string where a float belongs)
  • ValueError — right type, bad value (float("abc"))
  • IndexError — list index out of range
  • FileNotFoundError — path wrong or file not mounted
  • ZeroDivisionError — empty batch used as a denominator

try / except / else / finally

Catch specific exceptions. except Exception: swallows bugs; a bare except: also catches Ctrl+C and should never appear in your code.

else runs when no exception occurred. finally always runs — use it to release resources.

raise re-raises the current exception after logging. raise ValueError("msg") from err preserves the original cause, which keeps the traceback useful.

Define your own exception types for domain errors: class RetrievalError(Exception): pass. Callers can then handle your failure mode without guessing at strings.

Retry with backoff

Transient failures (429 rate limits, 503, timeouts) deserve a retry. Permanent ones (401 auth, 400 bad request) do not — retrying them just burns quota.

Standard shape: try, catch the transient type, sleep for an increasing delay (2 ** attempt), try again up to N times, then give up and raise. Production code adds jitter so a fleet of workers does not retry in lockstep.

Copy-paste examples

Copy into your own editor, or load one into the compiler below and press Run.

Catch specific exceptions

Each block handles one failure mode with a useful message.

payload = {"model": "gpt-4.1-mini"}

try:
    temperature = float(payload["temperature"])
except KeyError:
    temperature = 0.2
    print("temperature missing, using default")
except (TypeError, ValueError):
    temperature = 0.2
    print("temperature unparseable, using default")
else:
    print("parsed temperature")
finally:
    print("temperature =", temperature)

Custom exception + raise from

Domain errors let callers handle your failure without string matching.

class RetrievalError(Exception):
    pass

def retrieve(query, index):
    try:
        return index[query]
    except KeyError as err:
        raise RetrievalError(f"no documents for: {query}") from err

index = {"python": ["doc-1", "doc-2"]}
print(retrieve("python", index))

try:
    retrieve("rust", index)
except RetrievalError as err:
    print("handled:", err)
    print("caused by:", type(err.__cause__).__name__)

Retry with exponential backoff

Simulated flaky API. Real code sleeps with time.sleep and adds jitter.

attempts = {"count": 0}

def flaky_call():
    attempts["count"] += 1
    if attempts["count"] < 3:
        raise TimeoutError("upstream timeout")
    return {"answer": "ok"}

def call_with_retry(fn, max_attempts=5):
    for attempt in range(max_attempts):
        try:
            return fn()
        except TimeoutError as err:
            wait = 2 ** attempt
            print(f"attempt {attempt + 1} failed ({err}); retry in {wait}s")
    raise RuntimeError("all retries exhausted")

print(call_with_retry(flaky_call))

Validate an LLM config safely

Try it — in-browser Python

Set temperature to "hot" or delete the key and see which branch runs.

Output

Python runs in your browser. First run downloads the runtime.

Press Run (or Ctrl+Enter) to execute.

CPython in WebAssembly. Stdlib works. NumPy and pandas load on demand. No input(), no GPU, no network installs.

Takeaways

  • Read tracebacks bottom-up; the last line names the real problem.
  • Catch specific exceptions — never use a bare except.
  • Retry transient failures with backoff; fail fast on auth and validation errors.