cjm-error-handling


Namecjm-error-handling JSON
Version 0.0.2 PyPI version JSON
download
home_pagehttps://github.com/cj-mills/cjm-error-handling
SummaryStructured error handling with context propagation, user-friendly messaging, and serialization support for reusable Python libraries.
upload_time2025-10-29 17:20:11
maintainerNone
docs_urlNone
authorChristian J. Mills
requires_python>=3.9
licenseApache Software License 2.0
keywords nbdev jupyter notebook python
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # cjm-error-handling


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

## Install

``` sh
pip install cjm_error_handling
```

## Project Structure

    nbs/
    ├── core/ (2)
    │   ├── base.ipynb    # Foundation classes for structured error handling with context propagation and dual messaging
    │   └── errors.ipynb  # Concrete error classes for common failure scenarios in library ecosystems
    └── utils/ (1)
        └── helpers.ipynb  # Utilities for easy adoption and incremental migration to structured error handling

Total: 3 notebooks across 2 directories

## Module Dependencies

``` mermaid
graph LR
    core_base[core.base<br/>Base Error Classes]
    core_errors[core.errors<br/>Domain-Specific Error Types]
    utils_helpers[utils.helpers<br/>Helper Utilities]

    core_errors --> core_base
    utils_helpers --> core_errors
    utils_helpers --> core_base
```

*3 cross-module dependencies detected*

## CLI Reference

No CLI commands found in this project.

## Module Overview

Detailed documentation for each module in the project:

### Base Error Classes (`base.ipynb`)

> Foundation classes for structured error handling with context
> propagation and dual messaging

#### Import

``` python
from cjm_error_handling.core.base import (
    ErrorSeverity,
    ErrorContext,
    BaseError
)
```

#### Classes

``` python
class ErrorSeverity(Enum):
    "Error severity levels for categorization and handling."
```

``` python
@dataclass
class ErrorContext:
    "Structured context information for errors."
    
    job_id: Optional[str]  # Job identifier
    plugin_id: Optional[str]  # Plugin identifier
    worker_pid: Optional[int]  # Worker process ID
    session_id: Optional[str]  # Session identifier
    user_id: Optional[str]  # User identifier
    operation: Optional[str]  # Operation being performed
    timestamp: str = field(...)  # When error occurred
    extra: Dict[str, Any] = field(...)  # Domain-specific context
    
    def to_dict(self) -> Dict[str, Any]:  # Dictionary representation
            """Convert context to dictionary for serialization."""
            result = asdict(self)
            # Remove None values for cleaner serialization
            return {k: v for k, v in result.items() if v is not None}
        "Convert context to dictionary for serialization."
    
    def from_dict(cls, data: Dict[str, Any]) -> 'ErrorContext':  # ErrorContext instance
            """Create ErrorContext from dictionary."""
            # Extract known fields
            known_fields = {'job_id', 'plugin_id', 'worker_pid', 'session_id',
                           'user_id', 'operation', 'timestamp'}
            kwargs = {k: v for k, v in data.items() if k in known_fields}
        "Create ErrorContext from dictionary."
```

``` python
class BaseError:
    def __init__(
        self,
        message: str,                              # User-friendly error message
        debug_info: Optional[str] = None,          # Optional developer details
        context: Optional[ErrorContext] = None,    # Structured error context
        severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level
        is_retryable: bool = False,                # Whether error is transient/retryable
        cause: Optional[Exception] = None          # Original exception if chaining
    )
    "Base exception class with rich context and dual messaging."
    
    def __init__(
            self,
            message: str,                              # User-friendly error message
            debug_info: Optional[str] = None,          # Optional developer details
            context: Optional[ErrorContext] = None,    # Structured error context
            severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level
            is_retryable: bool = False,                # Whether error is transient/retryable
            cause: Optional[Exception] = None          # Original exception if chaining
        )
        "Initialize error with message, context, and metadata."
    
    def get_user_message(self) -> str:  # User-friendly message
            """Get the user-friendly error message."""
            return self.message
    
        def get_debug_message(self) -> str:  # Debug message with details
        "Get the user-friendly error message."
    
    def get_debug_message(self) -> str:  # Debug message with details
            """Get detailed debug information."""
            parts = [self.message]
    
            if self.debug_info
        "Get detailed debug information."
    
    def to_dict(self) -> Dict[str, Any]:  # Dictionary representation
            """Serialize error to dictionary for transmission across process boundaries."""
            result = {
                'error_type': self.__class__.__name__,
        "Serialize error to dictionary for transmission across process boundaries."
    
    def from_dict(cls, data: Dict[str, Any]) -> 'BaseError':  # Reconstructed error
            """Reconstruct error from dictionary representation."""
            # Reconstruct context
            context = ErrorContext.from_dict(data.get('context', {}))
    
            # Reconstruct severity
            severity_str = data.get('severity', 'error')
            severity = ErrorSeverity(severity_str)
    
            # Note: We can't reconstruct the original cause exception,
        "Reconstruct error from dictionary representation."
```

### Domain-Specific Error Types (`errors.ipynb`)

> Concrete error classes for common failure scenarios in library
> ecosystems

#### Import

``` python
from cjm_error_handling.core.errors import (
    ValidationError,
    ConfigurationError,
    ResourceError,
    PluginError,
    WorkerError
)
```

#### Classes

``` python
class ValidationError:
    def __init__(
        self,
        message: str,                              # User-friendly error message
        debug_info: Optional[str] = None,          # Optional developer details
        context: Optional[ErrorContext] = None,    # Structured error context
        severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level
        is_retryable: bool = False,                # Validation errors typically need fixes, not retries
        cause: Optional[Exception] = None,         # Original exception if chaining
        validation_errors: Optional[Dict[str, Any]] = None  # Structured validation details
    )
    "Raised when validation fails."
    
    def __init__(
            self,
            message: str,                              # User-friendly error message
            debug_info: Optional[str] = None,          # Optional developer details
            context: Optional[ErrorContext] = None,    # Structured error context
            severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level
            is_retryable: bool = False,                # Validation errors typically need fixes, not retries
            cause: Optional[Exception] = None,         # Original exception if chaining
            validation_errors: Optional[Dict[str, Any]] = None  # Structured validation details
        )
        "Initialize validation error with optional structured validation details."
    
    def to_dict(self) -> Dict[str, Any]:  # Dictionary representation
            """Serialize error including validation details."""
            result = super().to_dict()
            if self.validation_errors
        "Serialize error including validation details."
```

``` python
class ConfigurationError:
    def __init__(
        self,
        message: str,                              # User-friendly error message
        debug_info: Optional[str] = None,          # Optional developer details
        context: Optional[ErrorContext] = None,    # Structured error context
        severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level
        is_retryable: bool = False,                # Config issues usually need manual fixes
        cause: Optional[Exception] = None,         # Original exception if chaining
        config_path: Optional[str] = None          # Path to problematic config file
    )
    "Raised when configuration operations fail."
    
    def __init__(
            self,
            message: str,                              # User-friendly error message
            debug_info: Optional[str] = None,          # Optional developer details
            context: Optional[ErrorContext] = None,    # Structured error context
            severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level
            is_retryable: bool = False,                # Config issues usually need manual fixes
            cause: Optional[Exception] = None,         # Original exception if chaining
            config_path: Optional[str] = None          # Path to problematic config file
        )
        "Initialize configuration error with optional config file path."
    
    def to_dict(self) -> Dict[str, Any]:  # Dictionary representation
            """Serialize error including config path."""
            result = super().to_dict()
            if self.config_path
        "Serialize error including config path."
```

``` python
class ResourceError:
    def __init__(
        self,
        message: str,                              # User-friendly error message
        debug_info: Optional[str] = None,          # Optional developer details
        context: Optional[ErrorContext] = None,    # Structured error context
        severity: ErrorSeverity = ErrorSeverity.WARNING,  # Often transient
        is_retryable: bool = True,                 # Resource conflicts may be temporary
        cause: Optional[Exception] = None,         # Original exception if chaining
        resource_type: Optional[str] = None,       # "GPU", "Memory", "Disk", etc.
        suggested_action: Optional[str] = None     # Guidance for resolution
    )
    "Raised when resource conflicts or unavailability prevent operation."
    
    def __init__(
            self,
            message: str,                              # User-friendly error message
            debug_info: Optional[str] = None,          # Optional developer details
            context: Optional[ErrorContext] = None,    # Structured error context
            severity: ErrorSeverity = ErrorSeverity.WARNING,  # Often transient
            is_retryable: bool = True,                 # Resource conflicts may be temporary
            cause: Optional[Exception] = None,         # Original exception if chaining
            resource_type: Optional[str] = None,       # "GPU", "Memory", "Disk", etc.
            suggested_action: Optional[str] = None     # Guidance for resolution
        )
        "Initialize resource error with resource type and suggested action."
    
    def to_dict(self) -> Dict[str, Any]:  # Dictionary representation
            """Serialize error including resource type and suggested action."""
            result = super().to_dict()
            if self.resource_type
        "Serialize error including resource type and suggested action."
```

``` python
class PluginError:
    def __init__(
        self,
        message: str,                              # User-friendly error message
        debug_info: Optional[str] = None,          # Optional developer details
        context: Optional[ErrorContext] = None,    # Structured error context
        severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level
        is_retryable: bool = False,                # Plugin errors usually need fixes
        cause: Optional[Exception] = None,         # Original exception if chaining
        plugin_id: Optional[str] = None,           # ID of problematic plugin
        plugin_name: Optional[str] = None          # Name of problematic plugin
    )
    "Raised when plugin operations fail."
    
    def __init__(
            self,
            message: str,                              # User-friendly error message
            debug_info: Optional[str] = None,          # Optional developer details
            context: Optional[ErrorContext] = None,    # Structured error context
            severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level
            is_retryable: bool = False,                # Plugin errors usually need fixes
            cause: Optional[Exception] = None,         # Original exception if chaining
            plugin_id: Optional[str] = None,           # ID of problematic plugin
            plugin_name: Optional[str] = None          # Name of problematic plugin
        )
        "Initialize plugin error with plugin ID and name."
    
    def to_dict(self) -> Dict[str, Any]:  # Dictionary representation
            """Serialize error including plugin ID and name."""
            result = super().to_dict()
            if self.plugin_id
        "Serialize error including plugin ID and name."
```

``` python
class WorkerError:
    def __init__(
        self,
        message: str,                              # User-friendly error message
        debug_info: Optional[str] = None,          # Optional developer details
        context: Optional[ErrorContext] = None,    # Structured error context
        severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level
        is_retryable: bool = True,                 # Worker errors may be transient
        cause: Optional[Exception] = None,         # Original exception if chaining
        worker_type: Optional[str] = None,         # "transcription", "llm", etc.
        job_id: Optional[str] = None               # Job that failed
    )
    "Raised when worker process operations fail."
    
    def __init__(
            self,
            message: str,                              # User-friendly error message
            debug_info: Optional[str] = None,          # Optional developer details
            context: Optional[ErrorContext] = None,    # Structured error context
            severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level
            is_retryable: bool = True,                 # Worker errors may be transient
            cause: Optional[Exception] = None,         # Original exception if chaining
            worker_type: Optional[str] = None,         # "transcription", "llm", etc.
            job_id: Optional[str] = None               # Job that failed
        )
        "Initialize worker error with worker type and job ID."
    
    def to_dict(self) -> Dict[str, Any]:  # Dictionary representation
            """Serialize error including worker type and job ID."""
            result = super().to_dict()
            if self.worker_type
        "Serialize error including worker type and job ID."
```

### Helper Utilities (`helpers.ipynb`)

> Utilities for easy adoption and incremental migration to structured
> error handling

#### Import

``` python
from cjm_error_handling.utils.helpers import (
    error_boundary,
    with_error_handling,
    wrap_exception,
    chain_error
)
```

#### Functions

``` python
@contextmanager
def error_boundary(
    error_type: Type[BaseError] = BaseError,  # Error type to raise
    message: Optional[str] = None,  # User-facing message (uses original if None)
    context: Optional[ErrorContext] = None,  # Error context
    operation: Optional[str] = None,  # Operation name (added to context)
    job_id: Optional[str] = None,  # Job ID (added to context)
    plugin_id: Optional[str] = None,  # Plugin ID (added to context)
    worker_pid: Optional[int] = None,  # Worker PID (added to context)
    severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity
    is_retryable: Optional[bool] = None,  # Override retryable flag
    catch: tuple = (Exception,),  # Exception types to catch
    **extra_context  # Additional context fields
)
    "Context manager that catches exceptions and wraps them in structured errors."
```

``` python
def with_error_handling(
    error_type: Type[BaseError] = BaseError,  # Error type to raise
    message: Optional[str] = None,  # User-facing message
    operation: Optional[str] = None,  # Operation name (uses function name if None)
    severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity
    is_retryable: Optional[bool] = None,  # Override retryable flag
    catch: tuple = (Exception,),  # Exception types to catch
    context_from_args: Optional[Dict[str, str]] = None  # Map arg names to context fields, e.g. {'job_id': 'job_id'}
)
    "Decorator that wraps function errors with structured error handling."
```

``` python
def wrap_exception(
    exception: Exception,  # Original exception to wrap
    error_type: Type[BaseError] = BaseError,  # Error type to create
    message: Optional[str] = None,  # User-facing message (uses exception if None)
    context: Optional[ErrorContext] = None,  # Error context
    severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity
    is_retryable: Optional[bool] = None,  # Override retryable flag
    **context_kwargs  # Additional context fields
) -> BaseError:  # Wrapped structured error
    "Wrap an existing exception in a structured error type."
```

``` python
def chain_error(
    base_error: BaseError,  # Original structured error
    new_message: str,  # New user-facing message
    error_type: Optional[Type[BaseError]] = None,  # New error type (uses base type if None)
    additional_context: Optional[Dict[str, Any]] = None,  # Additional context to add
    operation: Optional[str] = None,  # Update operation name
    severity: Optional[ErrorSeverity] = None  # Override severity
) -> BaseError:  # New error with chained context
    "Chain a structured error with additional context."
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/cj-mills/cjm-error-handling",
    "name": "cjm-error-handling",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "nbdev jupyter notebook python",
    "author": "Christian J. Mills",
    "author_email": "9126128+cj-mills@users.noreply.github.com",
    "download_url": "https://files.pythonhosted.org/packages/b4/b9/dce3b754aff60648b3f1a9d89a079bdf9d00d19cdc4c7d743df5c917659b/cjm_error_handling-0.0.2.tar.gz",
    "platform": null,
    "description": "# cjm-error-handling\n\n\n<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->\n\n## Install\n\n``` sh\npip install cjm_error_handling\n```\n\n## Project Structure\n\n    nbs/\n    \u251c\u2500\u2500 core/ (2)\n    \u2502   \u251c\u2500\u2500 base.ipynb    # Foundation classes for structured error handling with context propagation and dual messaging\n    \u2502   \u2514\u2500\u2500 errors.ipynb  # Concrete error classes for common failure scenarios in library ecosystems\n    \u2514\u2500\u2500 utils/ (1)\n        \u2514\u2500\u2500 helpers.ipynb  # Utilities for easy adoption and incremental migration to structured error handling\n\nTotal: 3 notebooks across 2 directories\n\n## Module Dependencies\n\n``` mermaid\ngraph LR\n    core_base[core.base<br/>Base Error Classes]\n    core_errors[core.errors<br/>Domain-Specific Error Types]\n    utils_helpers[utils.helpers<br/>Helper Utilities]\n\n    core_errors --> core_base\n    utils_helpers --> core_errors\n    utils_helpers --> core_base\n```\n\n*3 cross-module dependencies detected*\n\n## CLI Reference\n\nNo CLI commands found in this project.\n\n## Module Overview\n\nDetailed documentation for each module in the project:\n\n### Base Error Classes (`base.ipynb`)\n\n> Foundation classes for structured error handling with context\n> propagation and dual messaging\n\n#### Import\n\n``` python\nfrom cjm_error_handling.core.base import (\n    ErrorSeverity,\n    ErrorContext,\n    BaseError\n)\n```\n\n#### Classes\n\n``` python\nclass ErrorSeverity(Enum):\n    \"Error severity levels for categorization and handling.\"\n```\n\n``` python\n@dataclass\nclass ErrorContext:\n    \"Structured context information for errors.\"\n    \n    job_id: Optional[str]  # Job identifier\n    plugin_id: Optional[str]  # Plugin identifier\n    worker_pid: Optional[int]  # Worker process ID\n    session_id: Optional[str]  # Session identifier\n    user_id: Optional[str]  # User identifier\n    operation: Optional[str]  # Operation being performed\n    timestamp: str = field(...)  # When error occurred\n    extra: Dict[str, Any] = field(...)  # Domain-specific context\n    \n    def to_dict(self) -> Dict[str, Any]:  # Dictionary representation\n            \"\"\"Convert context to dictionary for serialization.\"\"\"\n            result = asdict(self)\n            # Remove None values for cleaner serialization\n            return {k: v for k, v in result.items() if v is not None}\n        \"Convert context to dictionary for serialization.\"\n    \n    def from_dict(cls, data: Dict[str, Any]) -> 'ErrorContext':  # ErrorContext instance\n            \"\"\"Create ErrorContext from dictionary.\"\"\"\n            # Extract known fields\n            known_fields = {'job_id', 'plugin_id', 'worker_pid', 'session_id',\n                           'user_id', 'operation', 'timestamp'}\n            kwargs = {k: v for k, v in data.items() if k in known_fields}\n        \"Create ErrorContext from dictionary.\"\n```\n\n``` python\nclass BaseError:\n    def __init__(\n        self,\n        message: str,                              # User-friendly error message\n        debug_info: Optional[str] = None,          # Optional developer details\n        context: Optional[ErrorContext] = None,    # Structured error context\n        severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level\n        is_retryable: bool = False,                # Whether error is transient/retryable\n        cause: Optional[Exception] = None          # Original exception if chaining\n    )\n    \"Base exception class with rich context and dual messaging.\"\n    \n    def __init__(\n            self,\n            message: str,                              # User-friendly error message\n            debug_info: Optional[str] = None,          # Optional developer details\n            context: Optional[ErrorContext] = None,    # Structured error context\n            severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level\n            is_retryable: bool = False,                # Whether error is transient/retryable\n            cause: Optional[Exception] = None          # Original exception if chaining\n        )\n        \"Initialize error with message, context, and metadata.\"\n    \n    def get_user_message(self) -> str:  # User-friendly message\n            \"\"\"Get the user-friendly error message.\"\"\"\n            return self.message\n    \n        def get_debug_message(self) -> str:  # Debug message with details\n        \"Get the user-friendly error message.\"\n    \n    def get_debug_message(self) -> str:  # Debug message with details\n            \"\"\"Get detailed debug information.\"\"\"\n            parts = [self.message]\n    \n            if self.debug_info\n        \"Get detailed debug information.\"\n    \n    def to_dict(self) -> Dict[str, Any]:  # Dictionary representation\n            \"\"\"Serialize error to dictionary for transmission across process boundaries.\"\"\"\n            result = {\n                'error_type': self.__class__.__name__,\n        \"Serialize error to dictionary for transmission across process boundaries.\"\n    \n    def from_dict(cls, data: Dict[str, Any]) -> 'BaseError':  # Reconstructed error\n            \"\"\"Reconstruct error from dictionary representation.\"\"\"\n            # Reconstruct context\n            context = ErrorContext.from_dict(data.get('context', {}))\n    \n            # Reconstruct severity\n            severity_str = data.get('severity', 'error')\n            severity = ErrorSeverity(severity_str)\n    \n            # Note: We can't reconstruct the original cause exception,\n        \"Reconstruct error from dictionary representation.\"\n```\n\n### Domain-Specific Error Types (`errors.ipynb`)\n\n> Concrete error classes for common failure scenarios in library\n> ecosystems\n\n#### Import\n\n``` python\nfrom cjm_error_handling.core.errors import (\n    ValidationError,\n    ConfigurationError,\n    ResourceError,\n    PluginError,\n    WorkerError\n)\n```\n\n#### Classes\n\n``` python\nclass ValidationError:\n    def __init__(\n        self,\n        message: str,                              # User-friendly error message\n        debug_info: Optional[str] = None,          # Optional developer details\n        context: Optional[ErrorContext] = None,    # Structured error context\n        severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level\n        is_retryable: bool = False,                # Validation errors typically need fixes, not retries\n        cause: Optional[Exception] = None,         # Original exception if chaining\n        validation_errors: Optional[Dict[str, Any]] = None  # Structured validation details\n    )\n    \"Raised when validation fails.\"\n    \n    def __init__(\n            self,\n            message: str,                              # User-friendly error message\n            debug_info: Optional[str] = None,          # Optional developer details\n            context: Optional[ErrorContext] = None,    # Structured error context\n            severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level\n            is_retryable: bool = False,                # Validation errors typically need fixes, not retries\n            cause: Optional[Exception] = None,         # Original exception if chaining\n            validation_errors: Optional[Dict[str, Any]] = None  # Structured validation details\n        )\n        \"Initialize validation error with optional structured validation details.\"\n    \n    def to_dict(self) -> Dict[str, Any]:  # Dictionary representation\n            \"\"\"Serialize error including validation details.\"\"\"\n            result = super().to_dict()\n            if self.validation_errors\n        \"Serialize error including validation details.\"\n```\n\n``` python\nclass ConfigurationError:\n    def __init__(\n        self,\n        message: str,                              # User-friendly error message\n        debug_info: Optional[str] = None,          # Optional developer details\n        context: Optional[ErrorContext] = None,    # Structured error context\n        severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level\n        is_retryable: bool = False,                # Config issues usually need manual fixes\n        cause: Optional[Exception] = None,         # Original exception if chaining\n        config_path: Optional[str] = None          # Path to problematic config file\n    )\n    \"Raised when configuration operations fail.\"\n    \n    def __init__(\n            self,\n            message: str,                              # User-friendly error message\n            debug_info: Optional[str] = None,          # Optional developer details\n            context: Optional[ErrorContext] = None,    # Structured error context\n            severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level\n            is_retryable: bool = False,                # Config issues usually need manual fixes\n            cause: Optional[Exception] = None,         # Original exception if chaining\n            config_path: Optional[str] = None          # Path to problematic config file\n        )\n        \"Initialize configuration error with optional config file path.\"\n    \n    def to_dict(self) -> Dict[str, Any]:  # Dictionary representation\n            \"\"\"Serialize error including config path.\"\"\"\n            result = super().to_dict()\n            if self.config_path\n        \"Serialize error including config path.\"\n```\n\n``` python\nclass ResourceError:\n    def __init__(\n        self,\n        message: str,                              # User-friendly error message\n        debug_info: Optional[str] = None,          # Optional developer details\n        context: Optional[ErrorContext] = None,    # Structured error context\n        severity: ErrorSeverity = ErrorSeverity.WARNING,  # Often transient\n        is_retryable: bool = True,                 # Resource conflicts may be temporary\n        cause: Optional[Exception] = None,         # Original exception if chaining\n        resource_type: Optional[str] = None,       # \"GPU\", \"Memory\", \"Disk\", etc.\n        suggested_action: Optional[str] = None     # Guidance for resolution\n    )\n    \"Raised when resource conflicts or unavailability prevent operation.\"\n    \n    def __init__(\n            self,\n            message: str,                              # User-friendly error message\n            debug_info: Optional[str] = None,          # Optional developer details\n            context: Optional[ErrorContext] = None,    # Structured error context\n            severity: ErrorSeverity = ErrorSeverity.WARNING,  # Often transient\n            is_retryable: bool = True,                 # Resource conflicts may be temporary\n            cause: Optional[Exception] = None,         # Original exception if chaining\n            resource_type: Optional[str] = None,       # \"GPU\", \"Memory\", \"Disk\", etc.\n            suggested_action: Optional[str] = None     # Guidance for resolution\n        )\n        \"Initialize resource error with resource type and suggested action.\"\n    \n    def to_dict(self) -> Dict[str, Any]:  # Dictionary representation\n            \"\"\"Serialize error including resource type and suggested action.\"\"\"\n            result = super().to_dict()\n            if self.resource_type\n        \"Serialize error including resource type and suggested action.\"\n```\n\n``` python\nclass PluginError:\n    def __init__(\n        self,\n        message: str,                              # User-friendly error message\n        debug_info: Optional[str] = None,          # Optional developer details\n        context: Optional[ErrorContext] = None,    # Structured error context\n        severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level\n        is_retryable: bool = False,                # Plugin errors usually need fixes\n        cause: Optional[Exception] = None,         # Original exception if chaining\n        plugin_id: Optional[str] = None,           # ID of problematic plugin\n        plugin_name: Optional[str] = None          # Name of problematic plugin\n    )\n    \"Raised when plugin operations fail.\"\n    \n    def __init__(\n            self,\n            message: str,                              # User-friendly error message\n            debug_info: Optional[str] = None,          # Optional developer details\n            context: Optional[ErrorContext] = None,    # Structured error context\n            severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level\n            is_retryable: bool = False,                # Plugin errors usually need fixes\n            cause: Optional[Exception] = None,         # Original exception if chaining\n            plugin_id: Optional[str] = None,           # ID of problematic plugin\n            plugin_name: Optional[str] = None          # Name of problematic plugin\n        )\n        \"Initialize plugin error with plugin ID and name.\"\n    \n    def to_dict(self) -> Dict[str, Any]:  # Dictionary representation\n            \"\"\"Serialize error including plugin ID and name.\"\"\"\n            result = super().to_dict()\n            if self.plugin_id\n        \"Serialize error including plugin ID and name.\"\n```\n\n``` python\nclass WorkerError:\n    def __init__(\n        self,\n        message: str,                              # User-friendly error message\n        debug_info: Optional[str] = None,          # Optional developer details\n        context: Optional[ErrorContext] = None,    # Structured error context\n        severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level\n        is_retryable: bool = True,                 # Worker errors may be transient\n        cause: Optional[Exception] = None,         # Original exception if chaining\n        worker_type: Optional[str] = None,         # \"transcription\", \"llm\", etc.\n        job_id: Optional[str] = None               # Job that failed\n    )\n    \"Raised when worker process operations fail.\"\n    \n    def __init__(\n            self,\n            message: str,                              # User-friendly error message\n            debug_info: Optional[str] = None,          # Optional developer details\n            context: Optional[ErrorContext] = None,    # Structured error context\n            severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity level\n            is_retryable: bool = True,                 # Worker errors may be transient\n            cause: Optional[Exception] = None,         # Original exception if chaining\n            worker_type: Optional[str] = None,         # \"transcription\", \"llm\", etc.\n            job_id: Optional[str] = None               # Job that failed\n        )\n        \"Initialize worker error with worker type and job ID.\"\n    \n    def to_dict(self) -> Dict[str, Any]:  # Dictionary representation\n            \"\"\"Serialize error including worker type and job ID.\"\"\"\n            result = super().to_dict()\n            if self.worker_type\n        \"Serialize error including worker type and job ID.\"\n```\n\n### Helper Utilities (`helpers.ipynb`)\n\n> Utilities for easy adoption and incremental migration to structured\n> error handling\n\n#### Import\n\n``` python\nfrom cjm_error_handling.utils.helpers import (\n    error_boundary,\n    with_error_handling,\n    wrap_exception,\n    chain_error\n)\n```\n\n#### Functions\n\n``` python\n@contextmanager\ndef error_boundary(\n    error_type: Type[BaseError] = BaseError,  # Error type to raise\n    message: Optional[str] = None,  # User-facing message (uses original if None)\n    context: Optional[ErrorContext] = None,  # Error context\n    operation: Optional[str] = None,  # Operation name (added to context)\n    job_id: Optional[str] = None,  # Job ID (added to context)\n    plugin_id: Optional[str] = None,  # Plugin ID (added to context)\n    worker_pid: Optional[int] = None,  # Worker PID (added to context)\n    severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity\n    is_retryable: Optional[bool] = None,  # Override retryable flag\n    catch: tuple = (Exception,),  # Exception types to catch\n    **extra_context  # Additional context fields\n)\n    \"Context manager that catches exceptions and wraps them in structured errors.\"\n```\n\n``` python\ndef with_error_handling(\n    error_type: Type[BaseError] = BaseError,  # Error type to raise\n    message: Optional[str] = None,  # User-facing message\n    operation: Optional[str] = None,  # Operation name (uses function name if None)\n    severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity\n    is_retryable: Optional[bool] = None,  # Override retryable flag\n    catch: tuple = (Exception,),  # Exception types to catch\n    context_from_args: Optional[Dict[str, str]] = None  # Map arg names to context fields, e.g. {'job_id': 'job_id'}\n)\n    \"Decorator that wraps function errors with structured error handling.\"\n```\n\n``` python\ndef wrap_exception(\n    exception: Exception,  # Original exception to wrap\n    error_type: Type[BaseError] = BaseError,  # Error type to create\n    message: Optional[str] = None,  # User-facing message (uses exception if None)\n    context: Optional[ErrorContext] = None,  # Error context\n    severity: ErrorSeverity = ErrorSeverity.ERROR,  # Error severity\n    is_retryable: Optional[bool] = None,  # Override retryable flag\n    **context_kwargs  # Additional context fields\n) -> BaseError:  # Wrapped structured error\n    \"Wrap an existing exception in a structured error type.\"\n```\n\n``` python\ndef chain_error(\n    base_error: BaseError,  # Original structured error\n    new_message: str,  # New user-facing message\n    error_type: Optional[Type[BaseError]] = None,  # New error type (uses base type if None)\n    additional_context: Optional[Dict[str, Any]] = None,  # Additional context to add\n    operation: Optional[str] = None,  # Update operation name\n    severity: Optional[ErrorSeverity] = None  # Override severity\n) -> BaseError:  # New error with chained context\n    \"Chain a structured error with additional context.\"\n```\n",
    "bugtrack_url": null,
    "license": "Apache Software License 2.0",
    "summary": "Structured error handling with context propagation, user-friendly messaging, and serialization support for reusable Python libraries.",
    "version": "0.0.2",
    "project_urls": {
        "Homepage": "https://github.com/cj-mills/cjm-error-handling"
    },
    "split_keywords": [
        "nbdev",
        "jupyter",
        "notebook",
        "python"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "a8883b16545515b6962ba6a59a26df0d0d419945cf84d6cee2f5d1cac41e0697",
                "md5": "16e82ece2c53632672d07934362ad171",
                "sha256": "419525155e47b5c2b4755341ae389cc48fe5d614b0d2bdfcc2e081d50514978a"
            },
            "downloads": -1,
            "filename": "cjm_error_handling-0.0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "16e82ece2c53632672d07934362ad171",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 16309,
            "upload_time": "2025-10-29T17:20:10",
            "upload_time_iso_8601": "2025-10-29T17:20:10.164143Z",
            "url": "https://files.pythonhosted.org/packages/a8/88/3b16545515b6962ba6a59a26df0d0d419945cf84d6cee2f5d1cac41e0697/cjm_error_handling-0.0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b4b9dce3b754aff60648b3f1a9d89a079bdf9d00d19cdc4c7d743df5c917659b",
                "md5": "3eeb9aa8c272bd7ca45ea584fb2c162a",
                "sha256": "2d1181a5b2f8e857594ab735441c1aba7e6f70dca48361e7d0fcc0d7f9548b81"
            },
            "downloads": -1,
            "filename": "cjm_error_handling-0.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "3eeb9aa8c272bd7ca45ea584fb2c162a",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 17246,
            "upload_time": "2025-10-29T17:20:11",
            "upload_time_iso_8601": "2025-10-29T17:20:11.666121Z",
            "url": "https://files.pythonhosted.org/packages/b4/b9/dce3b754aff60648b3f1a9d89a079bdf9d00d19cdc4c7d743df5c917659b/cjm_error_handling-0.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-29 17:20:11",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "cj-mills",
    "github_project": "cjm-error-handling",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "cjm-error-handling"
}
        
Elapsed time: 2.09452s