AI Skill Report Card

Handling Python Exceptions and Warnings

A90·Aug 13, 2026·Source: Web
14 / 15
Python
# Raise the most specific built-in exception that fits def get_item(d, key): if key not in d: raise KeyError(f"{key!r} not found") return d[key] # Chain exceptions to preserve context try: get_item({}, "x") except KeyError as e: raise RuntimeError("lookup failed") from e # Emit a warning instead of failing hard import warnings def old_api(): warnings.warn("old_api() is deprecated, use new_api()", DeprecationWarning, stacklevel=2)
Recommendation
Add an example showing a bad/anti-pattern output alongside a good one for contrast
14 / 15

Progress checklist for designing error handling:

  • Identify the failure mode: programmer error, runtime/environment error, or a non-fatal condition
  • Pick the narrowest matching built-in exception/warning class (see table below)
  • If no built-in fits, define a custom exception inheriting from the closest built-in base
  • Decide whether to chain (raise X from Y) or suppress (raise X from None) the causing exception
  • Use try/except/else/finally correctly: else for success-only code, finally for cleanup
  • For warnings, choose the right category and set stacklevel so the reported location is the caller's
  • Configure warning filters only at the application entry point, not inside library code

Exception class selection

SituationUse
Wrong type passedTypeError
Value of correct type but invalidValueError
Key missing from mappingKeyError
Index out of rangeIndexError
Attribute doesn't existAttributeError
Name not foundNameError (usually not raised manually)
Operation not supported / not yet implementedNotImplementedError
Feature unsupported on this platform/configNotImplementedError or custom
Invalid internal state / logic bugAssertionError (via assert) or RuntimeError
File/OS-level errorsOSError (and subclasses: FileNotFoundError, PermissionError, IsADirectoryError, TimeoutError)
Arithmetic problemsArithmeticError subclasses: ZeroDivisionError, OverflowError
Iteration exhaustedStopIteration (don't catch manually in generators)
User interrupted programKeyboardInterrupt (never catch broadly)
Recursion too deepRecursionError
Custom domain errorSubclass Exception directly (never subclass BaseException unless it must escape normal handling like SystemExit)

Warning category selection

SituationUse
API scheduled for removal, visible to end usersDeprecationWarning
Deprecation only relevant to other library authorsPendingDeprecationWarning
Code likely has a bugRuntimeWarning
Syntax is deprecated/questionableSyntaxWarning
Use of obsolete feature that still worksFutureWarning (user-facing, unlike DeprecationWarning)
Import-related issueImportWarning
Unicode-related issueUnicodeWarning
Bytes/bytearray related issueBytesWarning
Resource not cleaned up (e.g., unclosed file)ResourceWarning
Custom categorySubclass Warning
Recommendation
Include a brief example of warning filter configuration at an application entry point
18 / 20

Example 1: Wrapping a low-level error with context Input:

Python
def load_config(path): with open(path) as f: return parse(f.read())

Output:

Python
def load_config(path): try: with open(path) as f: return parse(f.read()) except OSError as e: raise RuntimeError(f"could not load config from {path}") from e except ValueError as e: raise RuntimeError(f"config at {path} is malformed") from e

Example 2: Deprecating a function Input: def send(msg): ... needs to be replaced by send_message(msg). Output:

Python
import warnings def send(msg): warnings.warn( "send() is deprecated since v2.0; use send_message() instead", DeprecationWarning, stacklevel=2, ) return send_message(msg)

Example 3: Custom exception hierarchy Input: A library needs its own errors for a parsing module. Output:

Python
class ParserError(Exception): """Base class for all parser errors.""" class SyntaxParseError(ParserError): """Raised when input violates grammar rules.""" class EncodingParseError(ParserError, ValueError): """Raised when input encoding is invalid."""

Example 4: Suppressing exception chaining Input: Re-raising a domain error without leaking internal details. Output:

Python
try: _internal_lookup(key) except _InternalKeyMiss: raise KeyError(key) from None
Recommendation
Consider trimming the two reference tables slightly or merging overlapping rows for conciseness
  • Prefer the most specific built-in exception; only create a custom one when none fits.
  • Always inherit custom exceptions from Exception, not BaseException.
  • Use raise ... from err to preserve the traceback chain; use from None to intentionally hide internal implementation exceptions.
  • Use stacklevel=2 (or higher) in warnings.warn so the warning points to the caller, not the library internals.
  • Catch narrow exception types; avoid bare except: or broad except Exception: unless re-raising or logging at a top-level boundary.
  • Use else clause in try blocks for code that should only run when no exception occurred.
  • Use finally for cleanup that must run regardless of success/failure (or prefer context managers).
  • Group related exceptions with except (TypeError, ValueError): rather than duplicating handler bodies.
  • For libraries, never call warnings.simplefilter or change global filter state — that's the application's decision.
  • Don't catch BaseException, KeyboardInterrupt, or SystemExit unintentionally with a bare except:.
  • Don't swallow exceptions silently (except Exception: pass) — at minimum log them.
  • Don't raise a bare Exception() or RuntimeError() for everything — it loses semantic meaning for callers.
  • Don't forget stacklevel in warnings.warn; default (1) makes the warning appear to originate inside your own function.
  • Don't use warnings for conditions that should actually stop execution — that's what exceptions are for.
  • Don't mutate __traceback__ or re-raise without from when context is genuinely useful for debugging.
  • Don't subclass multiple unrelated exception bases without checking MRO consistency (e.g., mixing ValueError and TypeError bases can create confusing catches).
0
Grade AAI Skill Framework
Scorecard
Criteria Breakdown
Quick Start
14/15
Workflow
14/15
Examples
18/20
Completeness
19/20
Format
15/15
Conciseness
14/15