# Helper Utilities


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

## Adoption Utilities

These utilities make it easy to incrementally adopt structured error
handling in existing codebases without requiring large-scale
refactoring.

## error_boundary

A context manager that automatically enriches exceptions with context
and converts them to structured errors.

------------------------------------------------------------------------

### error_boundary

``` python

def error_boundary(
    error_type:Type=BaseError, # Error type to raise
    message:Optional=None, # User-facing message (uses original if None)
    context:Optional=None, # Error context
    operation:Optional=None, # Operation name (added to context)
    job_id:Optional=None, # Job ID (added to context)
    plugin_id:Optional=None, # Plugin ID (added to context)
    worker_pid:Optional=None, # Worker PID (added to context)
    severity:ErrorSeverity=<ErrorSeverity.ERROR: 'error'>, # Error severity
    is_retryable:Optional=None, # Override retryable flag
    catch:tuple=(<class 'Exception'>,), # Exception types to catch
    extra_context:VAR_KEYWORD
):

```

*Context manager that catches exceptions and wraps them in structured
errors.*

### Example: error_boundary

``` python
# Basic usage - wrap existing code
try:
    with error_boundary(
        error_type=ConfigurationError,
        operation="load_config",
        message="Failed to load configuration"
    ):
        # Simulate config loading error
        raise FileNotFoundError("/config/settings.json")
except ConfigurationError as e:
    print(f"Caught: {type(e).__name__}")
    print(f"Message: {e.get_user_message()}")
    print(f"Debug: {e.get_debug_message()}")
    print(f"Context: {e.context.operation}")
```

    Caught: ConfigurationError
    Message: Failed to load configuration
    Debug: Failed to load configuration | Debug: Original error: FileNotFoundError: /config/settings.json | Caused by: FileNotFoundError: /config/settings.json
    Context: load_config

``` python
# With context fields
try:
    with error_boundary(
        error_type=PluginError,
        operation="initialize_plugin",
        plugin_id="whisper_large",
        model_path="/models/whisper-large-v3.pt"  # Extra context
    ):
        raise ImportError("No module named 'torch'")
except PluginError as e:
    print(f"\n{type(e).__name__}: {e.get_user_message()}")
    print(f"Plugin: {e.context.plugin_id}")
    print(f"Extra: {e.context.extra}")
```


    PluginError: No module named 'torch'
    Plugin: whisper_large
    Extra: {'model_path': '/models/whisper-large-v3.pt'}

## with_error_handling

A decorator that automatically wraps function errors with context.

------------------------------------------------------------------------

### with_error_handling

``` python

def with_error_handling(
    error_type:Type=BaseError, # Error type to raise
    message:Optional=None, # User-facing message
    operation:Optional=None, # Operation name (uses function name if None)
    severity:ErrorSeverity=<ErrorSeverity.ERROR: 'error'>, # Error severity
    is_retryable:Optional=None, # Override retryable flag
    catch:tuple=(<class 'Exception'>,), # Exception types to catch
    context_from_args:Optional=None, # Map arg names to context fields, e.g. {'job_id': 'job_id'}
):

```

*Decorator that wraps function errors with structured error handling.*

### Example: with_error_handling decorator

``` python
# Simple decorator usage
@with_error_handling(
    error_type=ValidationError,
    message="Configuration validation failed"
)
def validate_config(config):
    """Validate a configuration dictionary."""
    if 'model_id' not in config:
        raise ValueError("model_id is required")
    return True

# Test it
try:
    validate_config({})  # Missing model_id
except ValidationError as e:
    print(f"Caught: {type(e).__name__}")
    print(f"Message: {e.get_user_message()}")
    print(f"Operation: {e.context.operation}")
```

    Caught: ValidationError
    Message: Configuration validation failed
    Operation: validate_config

``` python
# With context from arguments
@with_error_handling(
    error_type=WorkerError,
    context_from_args={'job_id': 'job_id', 'worker_pid': 'worker_pid'}
)
def execute_job(job_id, worker_pid, data):
    """Execute a job in a worker."""
    if data is None:
        raise RuntimeError("No data provided")
    return f"Processed {data}"

# Test it
try:
    execute_job(job_id="job-123", worker_pid=54321, data=None)
except WorkerError as e:
    print(f"\n{type(e).__name__}: {e.get_user_message()}")
    print(f"Job ID: {e.context.job_id}")
    print(f"Worker PID: {e.context.worker_pid}")
    print(f"Operation: {e.context.operation}")
```


    WorkerError: No data provided
    Job ID: job-123
    Worker PID: 54321
    Operation: execute_job

## wrap_exception

Helper function to wrap an existing exception in a structured error
type.

------------------------------------------------------------------------

### wrap_exception

``` python

def wrap_exception(
    exception:Exception, # Original exception to wrap
    error_type:Type=BaseError, # Error type to create
    message:Optional=None, # User-facing message (uses exception if None)
    context:Optional=None, # Error context
    severity:ErrorSeverity=<ErrorSeverity.ERROR: 'error'>, # Error severity
    is_retryable:Optional=None, # Override retryable flag
    context_kwargs:VAR_KEYWORD
)->BaseError: # Wrapped structured error

```

*Wrap an existing exception in a structured error type.*

### Example: wrap_exception

``` python
# Wrap a caught exception
try:
    import json
    json.loads('{bad json}')
except json.JSONDecodeError as e:
    # Wrap in our error type
    error = wrap_exception(
        e,
        error_type=ConfigurationError,
        message="Failed to parse configuration file",
        operation="load_config",
        plugin_id="whisper_base"
    )
    
    print(f"Wrapped error: {type(error).__name__}")
    print(f"Message: {error.get_user_message()}")
    print(f"Debug: {error.get_debug_message()}")
    print(f"Context: {error.context.to_dict()}")
```

    Wrapped error: ConfigurationError
    Message: Failed to parse configuration file
    Debug: Failed to parse configuration file | Debug: Original: JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1) | Caused by: JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
    Context: {'plugin_id': 'whisper_base', 'operation': 'load_config', 'timestamp': '2026-04-14T05:31:46.024619', 'extra': {}}

## chain_error

Helper for explicit error chaining with enriched context.

------------------------------------------------------------------------

### chain_error

``` python

def chain_error(
    base_error:BaseError, # Original structured error
    new_message:str, # New user-facing message
    error_type:Optional=None, # New error type (uses base type if None)
    additional_context:Optional=None, # Additional context to add
    operation:Optional=None, # Update operation name
    severity:Optional=None, # Override severity
)->BaseError: # New error with chained context

```

*Chain a structured error with additional context.*

### Example: chain_error

``` python
# Simulate layered error handling
def load_config_file():
    """Low-level config loading."""
    raise ConfigurationError(
        message="Config file not found",
        debug_info="/config/whisper.json does not exist",
        context=ErrorContext(operation="read_file")
    )

def initialize_plugin():
    """Mid-level plugin initialization."""
    try:
        load_config_file()
    except ConfigurationError as e:
        # Chain with plugin context
        raise chain_error(
            e,
            new_message="Plugin initialization failed",
            error_type=PluginError,
            operation="initialize_plugin",
            additional_context={"plugin_name": "Whisper Large"}
        )

# Test chained errors
try:
    initialize_plugin()
except PluginError as e:
    print(f"Error type: {type(e).__name__}")
    print(f"Message: {e.get_user_message()}")
    print(f"Operation: {e.context.operation}")
    print(f"Extra context: {e.context.extra}")
    print(f"\nDebug (includes chain):")
    print(f"  {e.get_debug_message()}")
```

    Error type: PluginError
    Message: Plugin initialization failed
    Operation: initialize_plugin
    Extra context: {'plugin_name': 'Whisper Large'}

    Debug (includes chain):
      Plugin initialization failed | Debug: Config file not found | Debug: /config/whisper.json does not exist | Caused by: ConfigurationError: Config file not found

## Usage Summary

These utilities enable different adoption strategies:

### 1. Context Manager (Quickest)

Wrap existing code blocks:

``` python
with error_boundary(error_type=PluginError, plugin_id="whisper"):
    existing_code()
```

### 2. Decorator (Cleanest)

Annotate functions:

``` python
@with_error_handling(error_type=WorkerError)
def process_job(job_id):
    ...
```

### 3. Explicit Wrapping (Most Control)

Manually wrap in try/except:

``` python
try:
    risky_operation()
except Exception as e:
    error = wrap_exception(e, error_type=PluginError, plugin_id="whisper")
    raise error
```

### 4. Error Chaining (For Layers)

Add context as errors propagate:

``` python
try:
    lower_level_function()
except ConfigurationError as e:
    raise chain_error(e, "Higher level failed", operation="top_level")
```
