> **Navigation**: [Home](../index.md) > [Patterns](README.md) > Error Handling Patterns

# Error Handling Patterns

## Overview

This document provides comprehensive error handling patterns for ONEX infrastructure services. All error handling follows the transport-aware, context-rich pattern based on `ModelOnexError` hierarchy.

## Error Class Selection

Use the appropriate error class based on the failure scenario:

| Scenario | Error Class | When to Use |
|----------|-------------|-------------|
| Config invalid | `ProtocolConfigurationError` | Configuration validation fails, missing required fields, invalid formats |
| Secret not found | `SecretResolutionError` | Infisical secrets unavailable, decryption failures, expired credentials |
| Connection failed | `InfraConnectionError` | Network connectivity issues, service unreachable, DNS resolution failures |
| Timeout | `InfraTimeoutError` | Operation exceeds deadline, slow response times, hung connections |
| Auth failed | `InfraAuthenticationError` | Invalid credentials, expired tokens, permission denied |
| Rate limited | `InfraRateLimitedError` | HTTP 429 responses, API quota exceeded, throttling enforced |
| Unavailable | `InfraUnavailableError` | Service down, maintenance mode |

## Error Context Usage

All infrastructure errors must include rich context using `ModelInfraErrorContext`:

```python
from omnibase_infra.errors import InfraConnectionError, ModelInfraErrorContext
from omnibase_infra.enums import EnumInfraTransportType

context = ModelInfraErrorContext(
    transport_type=EnumInfraTransportType.DATABASE,
    operation="execute_query",
    target_name="postgresql-primary",
    correlation_id=request.correlation_id,
)
raise InfraConnectionError("Failed to connect to database", context=context) from original_error
```

### Context Fields

| Field | Type | Purpose | Example |
|-------|------|---------|---------|
| `transport_type` | `EnumInfraTransportType` | Service category | `DATABASE`, `KAFKA`, `INFISICAL` |
| `operation` | `str` | Specific operation attempted | `"execute_query"`, `"publish_message"` |
| `target_name` | `str` | Service instance identifier | `"postgresql-primary"`, `"kafka-broker-1"` |
| `correlation_id` | `UUID` | Request tracking ID | From incoming request envelope |

## Error Hierarchy

### ASCII Diagram

```
ModelOnexError (omnibase_core)
└── RuntimeHostError
    ├── ProtocolConfigurationError
    ├── SecretResolutionError
    ├── InfraConnectionError (transport-aware error codes)
    ├── InfraTimeoutError
    ├── InfraAuthenticationError
    ├── InfraRateLimitedError
    └── InfraUnavailableError
```

### Mermaid Diagram

```mermaid
flowchart TB
    accTitle: ONEX Error Class Hierarchy
    accDescr: Class hierarchy diagram showing the ONEX infrastructure error types. ModelOnexError from omnibase_core is the root. RuntimeHostError extends it, and seven specialized error types extend RuntimeHostError: ProtocolConfigurationError for invalid configs, SecretResolutionError for Infisical and secret issues, InfraConnectionError for network failures with transport-aware error codes, InfraTimeoutError for operation timeouts, InfraAuthenticationError for auth failures, InfraRateLimitedError for rate limiting and throttling, and InfraUnavailableError for service outages.

    ONEX["ModelOnexError<br/>(omnibase_core)"] --> RH["RuntimeHostError"]

    RH --> PCE["ProtocolConfigurationError<br/>Config validation failures"]
    RH --> SRE["SecretResolutionError<br/>Infisical/secret issues"]
    RH --> ICE["InfraConnectionError<br/>Network failures<br/>(transport-aware codes)"]
    RH --> ITE["InfraTimeoutError<br/>Operation timeouts"]
    RH --> IAE["InfraAuthenticationError<br/>Auth/credential failures"]
    RH --> IRLE["InfraRateLimitedError<br/>Rate limiting (429)"]
    RH --> IUE["InfraUnavailableError<br/>Service outages"]

    style ONEX fill:#e3f2fd
    style RH fill:#fff3e0
```

## Transport-Aware Error Codes

Error codes are automatically selected based on transport type:

| Transport | EnumCoreErrorCode | Use Cases |
|-----------|-------------------|-----------|
| DATABASE | `DATABASE_CONNECTION_ERROR` | PostgreSQL connection failures, query timeouts |
| HTTP/GRPC | `NETWORK_ERROR` | REST API failures, gRPC stream errors |
| KAFKA/CONSUL/INFISICAL/VALKEY | `SERVICE_UNAVAILABLE` | Message broker down, service registry unavailable |

### Transport Type Mapping

```python
from omnibase_infra.enums import EnumInfraTransportType

# Database operations
EnumInfraTransportType.DATABASE  # PostgreSQL, MySQL, etc.

# HTTP-based services
EnumInfraTransportType.HTTP      # REST APIs
EnumInfraTransportType.GRPC      # gRPC services

# Infrastructure services
EnumInfraTransportType.KAFKA     # Message broker
EnumInfraTransportType.CONSUL    # Service discovery
EnumInfraTransportType.INFISICAL  # Secret management
EnumInfraTransportType.VALKEY    # Cache layer
```

## Error Sanitization

For comprehensive error sanitization guidance, see [Error Sanitization Patterns](./error_sanitization_patterns.md).

### Quick Reference

**NEVER include** in error messages or context:
- Passwords, API keys, tokens, certificates
- Connection strings with credentials
- PII (names, emails, SSNs, phone numbers)
- Internal system paths with sensitive data

**SAFE to include**:
- Service names (sanitized identifiers)
- Operation names
- Correlation IDs
- Port numbers
- Error types and codes

### Quick Example

```python
# UNSAFE - exposes credentials
raise InfraConnectionError(
    f"Failed to connect to postgresql://admin:secret123@db.internal:5432/mydb"
)

# SAFE - sanitized target
context = ModelInfraErrorContext(
    transport_type=EnumInfraTransportType.DATABASE,
    operation="connect",
    target_name="postgresql-primary",  # Sanitized identifier
    correlation_id=correlation_id,
)
raise InfraConnectionError("Failed to connect to database", context=context)
```

For detailed implementation patterns including connection string sanitization, request/response sanitization, and logging integration, see [Error Sanitization Patterns](./error_sanitization_patterns.md).

## Complete Implementation Examples

### Database Connection Error

```python
from omnibase_infra.errors import InfraConnectionError, ModelInfraErrorContext
from omnibase_infra.enums import EnumInfraTransportType
from uuid import UUID

async def execute_query(
    query: str,
    correlation_id: UUID
) -> list[dict[str, object]]:
    try:
        conn = await asyncpg.connect(
            host=config.db_host,
            port=config.db_port,
            database=config.db_name,
        )
        return await conn.fetch(query)
    except asyncpg.PostgresConnectionError as e:
        context = ModelInfraErrorContext(
            transport_type=EnumInfraTransportType.DATABASE,
            operation="execute_query",
            target_name="postgresql-primary",
            correlation_id=correlation_id,
        )
        raise InfraConnectionError(
            "Failed to establish database connection",
            context=context
        ) from e
    except asyncpg.QueryCanceledError as e:
        context = ModelInfraErrorContext(
            transport_type=EnumInfraTransportType.DATABASE,
            operation="execute_query",
            target_name="postgresql-primary",
            correlation_id=correlation_id,
        )
        raise InfraTimeoutError(
            "Query execution exceeded timeout",
            context=context
        ) from e
```

### Kafka Publish Error

```python
from omnibase_infra.errors import InfraUnavailableError, ModelInfraErrorContext
from omnibase_infra.enums import EnumInfraTransportType
from kafka.errors import KafkaConnectionError

async def publish_event(
    topic: str,
    message: bytes,
    correlation_id: UUID
) -> None:
    try:
        await producer.send(topic, message)
    except KafkaConnectionError as e:
        context = ModelInfraErrorContext(
            transport_type=EnumInfraTransportType.KAFKA,
            operation="publish_message",
            target_name=f"kafka-topic-{topic}",
            correlation_id=correlation_id,
        )
        raise InfraUnavailableError(
            f"Kafka broker unavailable for topic {topic}",
            context=context
        ) from e
```

### Infisical Secret Retrieval Error

```python
from omnibase_infra.errors import SecretResolutionError, InfraAuthenticationError
from omnibase_infra.enums import EnumInfraTransportType

async def get_secret(
    path: str,
    correlation_id: UUID
) -> dict[str, str]:
    try:
        response = infisical_client.get_secret(path=path)
        return response.secret_value
    except SecretNotFoundError as e:
        # Secret doesn't exist - don't leak path structure
        raise SecretResolutionError(
            "Secret not found at requested path",
            context=ModelInfraErrorContext(
                transport_type=EnumInfraTransportType.INFISICAL,
                operation="get_secret",
                target_name="infisical-primary",
                correlation_id=correlation_id,
            )
        ) from e
    except UnauthorizedError as e:
        context = ModelInfraErrorContext(
            transport_type=EnumInfraTransportType.INFISICAL,
            operation="get_secret",
            target_name="infisical-primary",
            correlation_id=correlation_id,
        )
        raise InfraAuthenticationError(
            "Infisical authentication failed",
            context=context
        ) from e
```

## Error Chaining

Always chain errors to preserve stack traces:

```python
# ✅ CORRECT - preserves original error
raise InfraConnectionError("Connection failed", context=context) from original_error

# ❌ WRONG - loses original error
raise InfraConnectionError("Connection failed", context=context)
```

## Related Patterns

- [Security Patterns](./security_patterns.md) - Comprehensive security guide including error sanitization, input validation, authentication, and secret management
- [Error Sanitization Patterns](./error_sanitization_patterns.md) - Data classification, sanitization rules, and secure error reporting
- [Error Recovery Patterns](./error_recovery_patterns.md) - Retry logic, circuit breakers
- [Correlation ID Tracking](./correlation_id_tracking.md) - Request tracing across services
- [Container Dependency Injection](./container_dependency_injection.md) - Service resolution
