Search

PythonReactSEOPDF
GitHub Skill

error-handling

Error handling patterns including exception hierarchies, error messages, and recovery strategies. Activated when designing exceptions or error handling.

tbhb☆ 0 Repository stars0 Repository forks

Installation

Follow the repository instructions for this skill and your agent. Review the files and dependencies before adding it to your workflow.

View source ↗Guides

Skill instructions

Error handling

Purpose

Guide for designing robust error handling including exception hierarchies, clear error messages, and recovery strategies.

When to use

This skill activates when:

  • Designing exception classes
  • Writing error messages
  • Implementing error recovery
  • Creating diagnostic output
  • Handling validation errors

Core principles

Clear error messages
  • Tell user what went wrong
  • Tell user how to fix it
  • Include context (file, line, value)
Exception hierarchies
  • Create project-specific base exception
  • Categorize by error type
  • Enable selective catching

Exception hierarchy design

Base exception
class AppError(Exception):
    """Base exception for all application errors.

    All application-specific exceptions should inherit from this.
    Allows catching all application errors with one except clause.
    """
    pass
Categorized exceptions
class ValidationError(AppError):
    """Raised when validation fails."""

    def __init__(
        self,
        message: str,
        field: str | None = None,
        value: object = None,
    ) -> None:
        super().__init__(message)
        self.field = field
        self.value = value

    def __str__(self) -> str:
        if self.field:
            return f"{self.field}: {self.args[0]}"
        return self.args[0]


class ConfigurationError(AppError):
    """Raised when configuration is invalid."""

    def __init__(self, message: str, key: str | None = None) -> None:
        super().__init__(message)
        self.key = key


class ProcessingError(AppError):
    """Raised when processing fails."""

    def __init__(
        self,
        message: str,
        source: str | None = None,
        position: int | None = None,
    ) -> None:
        super().__init__(message)
        self.source = source
        self.position = position

Error message design

Good error messages
# Bad: Vague
raise ValueError("Invalid input")

# Good: Specific with context
raise ValidationError(
    f"Expected integer between 1 and 100, got {value!r}",
    field="count",
    value=value,
)

# Bad: Technical jargon
raise RuntimeError("NoneType has no attribute 'process'")

# Good: User-focused
raise ProcessingError(
    "Input file is empty or unreadable",
    source=filepath,
)
Error message pattern
def validate_count(value: int) -> int:
    """Validate count is in valid range.

    Error message pattern:
    1. What's wrong
    2. What was expected
    3. What was received
    4. How to fix (if applicable)
    """
    if value < 1:
        raise ValidationError(
            f"Count must be at least 1, got {value}. "
            "Provide a positive integer.",
            field="count",
            value=value,
        )

    if value > 100:
        raise ValidationError(
            f"Count cannot exceed 100, got {value}. "
            "Use a smaller value or process in batches.",
            field="count",
            value=value,
        )

    return value

Error recovery patterns

Try specific exceptions first
def process_file(path: Path) -> Result:
    """Process file with specific error handling."""
    try:
        content = path.read_text()
    except FileNotFoundError:
        raise ProcessingError(f"File not found: {path}")
    except PermissionError:
        raise ProcessingError(f"Cannot read file (permission denied): {path}")
    except OSError as e:
        raise ProcessingError(f"Cannot read file: {path} ({e})")

    try:
        return parse_content(content)
    except ParseError as e:
        raise ProcessingError(
            f"Invalid file format: {e}",
            source=str(path),
        )
Wrap low-level exceptions
def fetch_data(url: str) -> dict:
    """Fetch data with wrapped exceptions."""
    try:
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        return response.json()
    except requests.Timeout:
        raise ProcessingError(f"Request timed out: {url}")
    except requests.ConnectionError:
        raise ProcessingError(f"Cannot connect to server: {url}")
    except requests.HTTPError as e:
        raise ProcessingError(f"Server error ({e.response.status_code}): {url}")
    except ValueError:
        raise ProcessingError(f"Invalid JSON response from: {url}")
Aggregate multiple errors
class ValidationErrors(AppError):
    """Collection of validation errors."""

    def __init__(self, errors: list[ValidationError]) -> None:
        self.errors = errors
        messages = [str(e) for e in errors]
        super().__init__(f"Validation failed:\n" + "\n".join(f"  - {m}" for m in messages))

def validate_all(items: list[dict]) -> list[Item]:
    """Validate all items, collecting all errors."""
    errors: list[ValidationError] = []
    results: list[Item] = []

    for i, item in enumerate(items):
        try:
            results.append(validate_item(item))
        except ValidationError as e:
            e.field = f"items[{i}].{e.field}" if e.field else f"items[{i}]"
            errors.append(e)

    if errors:
        raise ValidationErrors(errors)

    return results

Logging vs raising

import logging

logger = logging.getLogger(__name__)

def process_batch(items: list[Item]) -> list[Result]:
    """Process items, logging warnings but raising on failures."""
    results = []

    for item in items:
        try:
            result = process_item(item)
            results.append(result)
        except RecoverableError as e:
            # Log warning, continue processing
            logger.warning(f"Skipping item {item.id}: {e}")
        except FatalError as e:
            # Log error, re-raise to stop processing
            logger.error(f"Fatal error processing {item.id}: {e}")
            raise

    return results

Checklist

  • Application-specific base exception defined
  • Exceptions categorized by error type
  • Error messages are clear and actionable
  • Context included (field, value, source)
  • Low-level exceptions wrapped appropriately
  • Recovery strategies appropriate for error types

Additional resources:

Examples

Read the usage examples in the source repository.

View source ↗

Source history

Indexed on
2026-01-20
Index updated
2026-01-26
Branch
main

Index and sync dates describe this directory. View the source repository for code history.

GitHub ↗

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!