# Error Handling - Unified Architecture Design

**Date**: 2025-10-12
**Status**: Design Phase
**Previous**: ERROR-HANDLING-AUDIT-REPORT.md
**Next**: ERROR-HANDLING-MIGRATION-PLAN.md

## Executive Summary

Dieses Dokument definiert die **Unified Exception Architecture** für das Framework. Das Design konsolidiert 4 separate Error-Module in ein einheitliches System unter `src/Framework/Exception/` mit automatischer Integration aller Komponenten.

**Design Goals**:
- ✅ Single Source of Truth für Error Handling
- ✅ Automatic integration (Pattern Detection, Reporting, Circuit Breaker)
- ✅ Backward compatibility mit bestehenden Code
- ✅ Improved developer experience
- ✅ Maintained functionality from all modules
- ✅ Performance optimization (async processing, batching)

## 1. New Module Structure

### Unified Directory Layout

```
src/Framework/Exception/
├── Core/                              # Core exception infrastructure
│   ├── FrameworkException.php         # Enhanced base exception
│   ├── ErrorCode.php                  # Enhanced with severity mapping
│   ├── ExceptionContext.php           # Unified context (Domain + Request + System)
│   ├── ErrorSeverity.php              # Moved from ErrorAggregation
│   └── ErrorLevel.php                 # Moved from ErrorHandling
│
├── Handler/                           # Global error handling
│   ├── ErrorHandler.php               # Integrated error handler
│   ├── ErrorLogger.php                # Structured logging
│   ├── ResponseFactory.php            # HTTP response creation
│   └── ContextBuilder.php             # ExceptionContext builder
│
├── Aggregation/                       # Pattern detection & alerting
│   ├── ErrorAggregator.php            # Auto-triggered pattern analysis
│   ├── ErrorEvent.php                 # Single error event VO
│   ├── ErrorPattern.php               # Pattern VO
│   ├── AlertManager.php               # Alert queuing
│   ├── PatternDetector.php            # Fingerprinting logic
│   └── Storage/
│       ├── ErrorStorageInterface.php
│       └── DatabaseErrorStorage.php   # Unified database storage
│
├── Reporting/                         # Error reporting & analytics
│   ├── ErrorReporter.php              # Auto-triggered reporting
│   ├── ErrorReport.php                # Report VO (extends ErrorEvent)
│   ├── AnalyticsEngine.php            # Velocity & anomaly detection
│   ├── ReportFilters/                 # Filter chain
│   └── ReportProcessors/              # Enrichment chain
│
├── Boundaries/                        # Resilience & circuit breaker
│   ├── ErrorBoundary.php              # Graceful degradation
│   ├── BoundaryConfig.php             # Configuration VO
│   ├── BoundaryResult.php             # Result pattern
│   ├── RetryStrategy.php              # Retry patterns
│   ├── CircuitBreaker/
│   │   ├── CircuitBreakerManager.php
│   │   └── CircuitState.php
│   └── Exceptions/
│       ├── BoundaryException.php      # Base boundary exception (extends FrameworkException)
│       ├── BoundaryTimeoutException.php
│       └── BoundaryFailedException.php
│
├── Http/                              # HTTP-specific exceptions
│   ├── HttpException.php              # Base HTTP exception
│   ├── NotFoundException.php
│   ├── UnauthorizedException.php
│   └── ...
│
├── Security/                          # Security exceptions
│   ├── SecurityException.php
│   ├── XssAttemptException.php
│   └── ...
│
├── Database/                          # Database exceptions
│   ├── DatabaseException.php
│   └── ...
│
├── Validation/                        # Validation exceptions
│   ├── ValidationException.php
│   └── ...
│
└── Migrations/                        # Database migrations
    ├── CreateErrorEventsTable.php
    └── CreateErrorPatternsTable.php
```

### Removed Directories

```
❌ src/Framework/ErrorHandling/        # Merged into Exception/Handler/
❌ src/Framework/ErrorAggregation/     # Merged into Exception/Aggregation/
❌ src/Framework/ErrorBoundaries/      # Merged into Exception/Boundaries/
❌ src/Framework/ErrorReporting/       # Merged into Exception/Reporting/
```

## 2. Core Components Design

### 2.1 Enhanced FrameworkException

**File**: `src/Framework/Exception/Core/FrameworkException.php`

```php
<?php

declare(strict_types=1);

namespace App\Framework\Exception\Core;

use App\Framework\Exception\Aggregation\ErrorAggregator;
use App\Framework\Exception\Reporting\ErrorReporter;

/**
 * Enhanced FrameworkException with automatic integration
 *
 * All framework exceptions MUST extend this class to ensure:
 * - Automatic pattern detection via ErrorAggregator
 * - Automatic error reporting via ErrorReporter
 * - Consistent error handling and context
 * - Circuit breaker integration
 */
class FrameworkException extends \RuntimeException
{
    protected ExceptionContext $context;
    protected ?ErrorCode $errorCode = null;
    protected ?int $retryAfter = null;

    // NEW: Automatic integration flags
    protected bool $skipAggregation = false;
    protected bool $skipReporting = false;
    protected bool $reported = false;

    public function __construct(
        string $message = '',
        int $code = 0,
        ?\Throwable $previous = null
    ) {
        parent::__construct($message, $code, $previous);
        $this->context = ExceptionContext::empty();
    }

    // ========================================
    // Factory Methods (existing + enhanced)
    // ========================================

    public static function simple(
        string $message,
        ?\Throwable $previous = null,
        int $httpStatus = 500
    ): static {
        $exception = new static($message, $httpStatus, $previous);
        return $exception;
    }

    public static function create(
        ErrorCode $errorCode,
        ?string $message = null
    ): static {
        $exception = new static($message ?? $errorCode->getDescription());
        $exception->errorCode = $errorCode;
        return $exception;
    }

    public static function forOperation(
        string $operation,
        ?string $component = null,
        ?string $message = null,
        ?ErrorCode $errorCode = null
    ): static {
        $exception = new static($message ?? "Error in {$operation}");
        $exception->context = ExceptionContext::forOperation($operation, $component);
        $exception->errorCode = $errorCode;
        return $exception;
    }

    public static function fromContext(
        string $message,
        ExceptionContext $context,
        ?ErrorCode $errorCode = null
    ): static {
        $exception = new static($message);
        $exception->context = $context;
        $exception->errorCode = $errorCode;
        return $exception;
    }

    // ========================================
    // Fluent API (existing)
    // ========================================

    public function withContext(ExceptionContext $context): self
    {
        $this->context = $context;
        return $this;
    }

    public function withOperation(string $operation, ?string $component = null): self
    {
        $this->context = $this->context->withOperation($operation, $component);
        return $this;
    }

    public function withData(array $data): self
    {
        $this->context = $this->context->withData($data);
        return $this;
    }

    public function withDebug(array $debug): self
    {
        $this->context = $this->context->withDebug($debug);
        return $this;
    }

    public function withMetadata(array $metadata): self
    {
        $this->context = $this->context->withMetadata($metadata);
        return $this;
    }

    public function withErrorCode(ErrorCode $errorCode): self
    {
        $this->errorCode = $errorCode;
        return $this;
    }

    public function withRetryAfter(int $seconds): self
    {
        $this->retryAfter = $seconds;
        return $this;
    }

    // NEW: Request/System context methods
    public function withRequestContext(
        string $requestId,
        string $method,
        string $uri,
        ?string $clientIp = null,
        ?string $userAgent = null
    ): self {
        $this->context = $this->context->withRequestContext(
            $requestId,
            $method,
            $uri,
            $clientIp,
            $userAgent
        );
        return $this;
    }

    public function withSystemContext(
        string $environment,
        string $hostname,
        float $memoryUsage,
        float $cpuUsage
    ): self {
        $this->context = $this->context->withSystemContext(
            $environment,
            $hostname,
            $memoryUsage,
            $cpuUsage
        );
        return $this;
    }

    // NEW: Integration control methods
    public function skipAggregation(): self
    {
        $this->skipAggregation = true;
        return $this;
    }

    public function skipReporting(): self
    {
        $this->skipReporting = true;
        return $this;
    }

    // ========================================
    // Getters
    // ========================================

    public function getContext(): ExceptionContext
    {
        return $this->context;
    }

    public function getErrorCode(): ?ErrorCode
    {
        return $this->errorCode;
    }

    public function getRetryAfter(): ?int
    {
        return $this->retryAfter;
    }

    // NEW: Get severity from ErrorCode
    public function getSeverity(): ErrorSeverity
    {
        return $this->errorCode?->getSeverity() ?? ErrorSeverity::ERROR;
    }

    // ========================================
    // Recovery Methods
    // ========================================

    public function isRecoverable(): bool
    {
        return $this->errorCode?->isRecoverable() ?? true;
    }

    public function getRecoveryHint(): ?string
    {
        return $this->errorCode?->getRecoveryHint();
    }

    // NEW: Check if already reported
    public function isReported(): bool
    {
        return $this->reported;
    }

    public function markAsReported(): void
    {
        $this->reported = true;
    }

    public function shouldSkipAggregation(): bool
    {
        return $this->skipAggregation;
    }

    public function shouldSkipReporting(): bool
    {
        return $this->skipReporting;
    }

    // ========================================
    // Category Helpers
    // ========================================

    public function isCategory(string $category): bool
    {
        if ($this->errorCode === null) {
            return false;
        }

        return $this->errorCode->getCategory() === $category;
    }

    public function isErrorCode(ErrorCode $errorCode): bool
    {
        return $this->errorCode === $errorCode;
    }

    // ========================================
    // Serialization
    // ========================================

    public function toArray(): array
    {
        return [
            'message' => $this->getMessage(),
            'code' => $this->getCode(),
            'error_code' => $this->errorCode?->value,
            'severity' => $this->getSeverity()->value,
            'context' => $this->context->toArray(),
            'file' => $this->getFile(),
            'line' => $this->getLine(),
            'recoverable' => $this->isRecoverable(),
            'retry_after' => $this->retryAfter,
            'recovery_hint' => $this->getRecoveryHint(),
        ];
    }
}
```

**Key Enhancements**:
1. ✅ Automatic integration flags (`skipAggregation`, `skipReporting`, `reported`)
2. ✅ Request/System context support via `withRequestContext()`, `withSystemContext()`
3. ✅ `getSeverity()` from ErrorCode
4. ✅ Integration control methods (`skipAggregation()`, `skipReporting()`)
5. ✅ Category helpers (`isCategory()`, `isErrorCode()`)

### 2.2 Unified ExceptionContext

**File**: `src/Framework/Exception/Core/ExceptionContext.php`

```php
<?php

declare(strict_types=1);

namespace App\Framework\Exception\Core;

/**
 * Unified ExceptionContext combining Domain + Request + System context
 *
 * Replaces both:
 * - ExceptionContext (old)
 * - ErrorHandlerContext (old)
 */
final readonly class ExceptionContext
{
    public function __construct(
        // Domain Context
        public ?string $operation = null,
        public ?string $component = null,
        public array $data = [],
        public array $debug = [],
        public array $metadata = [],

        // Request Context (NEW)
        public ?string $requestId = null,
        public ?string $requestMethod = null,
        public ?string $requestUri = null,
        public ?string $clientIp = null,
        public ?string $userAgent = null,
        public ?string $userId = null,

        // System Context (NEW)
        public ?string $environment = null,
        public ?string $hostname = null,
        public ?float $memoryUsage = null,
        public ?float $cpuUsage = null,
        public ?string $phpVersion = null,
    ) {
    }

    // ========================================
    // Factory Methods
    // ========================================

    public static function empty(): self
    {
        return new self();
    }

    public static function forOperation(string $operation, ?string $component = null): self
    {
        return new self(operation: $operation, component: $component);
    }

    public static function fromRequest(
        string $requestId,
        string $method,
        string $uri,
        ?string $clientIp = null,
        ?string $userAgent = null,
        ?string $userId = null
    ): self {
        return new self(
            requestId: $requestId,
            requestMethod: $method,
            requestUri: $uri,
            clientIp: $clientIp,
            userAgent: $userAgent,
            userId: $userId
        );
    }

    public static function fromSystem(): self
    {
        return new self(
            environment: $_ENV['APP_ENV'] ?? 'production',
            hostname: gethostname() ?: 'unknown',
            memoryUsage: memory_get_usage(true) / 1024 / 1024, // MB
            cpuUsage: sys_getloadavg()[0] ?? 0.0,
            phpVersion: PHP_VERSION
        );
    }

    // ========================================
    // Fluent API - Domain Context
    // ========================================

    public function withOperation(string $operation, ?string $component = null): self
    {
        return new self(
            operation: $operation,
            component: $component ?? $this->component,
            data: $this->data,
            debug: $this->debug,
            metadata: $this->metadata,
            requestId: $this->requestId,
            requestMethod: $this->requestMethod,
            requestUri: $this->requestUri,
            clientIp: $this->clientIp,
            userAgent: $this->userAgent,
            userId: $this->userId,
            environment: $this->environment,
            hostname: $this->hostname,
            memoryUsage: $this->memoryUsage,
            cpuUsage: $this->cpuUsage,
            phpVersion: $this->phpVersion
        );
    }

    public function withData(array $data): self
    {
        return new self(
            operation: $this->operation,
            component: $this->component,
            data: array_merge($this->data, $data),
            debug: $this->debug,
            metadata: $this->metadata,
            requestId: $this->requestId,
            requestMethod: $this->requestMethod,
            requestUri: $this->requestUri,
            clientIp: $this->clientIp,
            userAgent: $this->userAgent,
            userId: $this->userId,
            environment: $this->environment,
            hostname: $this->hostname,
            memoryUsage: $this->memoryUsage,
            cpuUsage: $this->cpuUsage,
            phpVersion: $this->phpVersion
        );
    }

    public function withDebug(array $debug): self
    {
        return new self(
            operation: $this->operation,
            component: $this->component,
            data: $this->data,
            debug: array_merge($this->debug, $debug),
            metadata: $this->metadata,
            requestId: $this->requestId,
            requestMethod: $this->requestMethod,
            requestUri: $this->requestUri,
            clientIp: $this->clientIp,
            userAgent: $this->userAgent,
            userId: $this->userId,
            environment: $this->environment,
            hostname: $this->hostname,
            memoryUsage: $this->memoryUsage,
            cpuUsage: $this->cpuUsage,
            phpVersion: $this->phpVersion
        );
    }

    public function withMetadata(array $metadata): self
    {
        return new self(
            operation: $this->operation,
            component: $this->component,
            data: $this->data,
            debug: $this->debug,
            metadata: array_merge($this->metadata, $metadata),
            requestId: $this->requestId,
            requestMethod: $this->requestMethod,
            requestUri: $this->requestUri,
            clientIp: $this->clientIp,
            userAgent: $this->userAgent,
            userId: $this->userId,
            environment: $this->environment,
            hostname: $this->hostname,
            memoryUsage: $this->memoryUsage,
            cpuUsage: $this->cpuUsage,
            phpVersion: $this->phpVersion
        );
    }

    // ========================================
    // Fluent API - Request Context
    // ========================================

    public function withRequestContext(
        string $requestId,
        string $method,
        string $uri,
        ?string $clientIp = null,
        ?string $userAgent = null,
        ?string $userId = null
    ): self {
        return new self(
            operation: $this->operation,
            component: $this->component,
            data: $this->data,
            debug: $this->debug,
            metadata: $this->metadata,
            requestId: $requestId,
            requestMethod: $method,
            requestUri: $uri,
            clientIp: $clientIp,
            userAgent: $userAgent,
            userId: $userId,
            environment: $this->environment,
            hostname: $this->hostname,
            memoryUsage: $this->memoryUsage,
            cpuUsage: $this->cpuUsage,
            phpVersion: $this->phpVersion
        );
    }

    public function withUserId(string $userId): self
    {
        return new self(
            operation: $this->operation,
            component: $this->component,
            data: $this->data,
            debug: $this->debug,
            metadata: $this->metadata,
            requestId: $this->requestId,
            requestMethod: $this->requestMethod,
            requestUri: $this->requestUri,
            clientIp: $this->clientIp,
            userAgent: $this->userAgent,
            userId: $userId,
            environment: $this->environment,
            hostname: $this->hostname,
            memoryUsage: $this->memoryUsage,
            cpuUsage: $this->cpuUsage,
            phpVersion: $this->phpVersion
        );
    }

    // ========================================
    // Fluent API - System Context
    // ========================================

    public function withSystemContext(
        string $environment,
        string $hostname,
        float $memoryUsage,
        float $cpuUsage
    ): self {
        return new self(
            operation: $this->operation,
            component: $this->component,
            data: $this->data,
            debug: $this->debug,
            metadata: $this->metadata,
            requestId: $this->requestId,
            requestMethod: $this->requestMethod,
            requestUri: $this->requestUri,
            clientIp: $this->clientIp,
            userAgent: $this->userAgent,
            userId: $this->userId,
            environment: $environment,
            hostname: $hostname,
            memoryUsage: $memoryUsage,
            cpuUsage: $cpuUsage,
            phpVersion: $this->phpVersion
        );
    }

    // ========================================
    // Getters (for backward compatibility)
    // ========================================

    public function getOperation(): ?string
    {
        return $this->operation;
    }

    public function getComponent(): ?string
    {
        return $this->component;
    }

    public function getData(): array
    {
        return $this->data;
    }

    public function getDebug(): array
    {
        return $this->debug;
    }

    public function getMetadata(): array
    {
        return $this->metadata;
    }

    // ========================================
    // Serialization
    // ========================================

    public function toArray(): array
    {
        return [
            // Domain context
            'operation' => $this->operation,
            'component' => $this->component,
            'data' => $this->sanitizeData($this->data),
            'debug' => $this->debug,
            'metadata' => $this->metadata,

            // Request context
            'request' => [
                'id' => $this->requestId,
                'method' => $this->requestMethod,
                'uri' => $this->requestUri,
                'client_ip' => $this->clientIp,
                'user_agent' => $this->userAgent,
                'user_id' => $this->userId,
            ],

            // System context
            'system' => [
                'environment' => $this->environment,
                'hostname' => $this->hostname,
                'memory_usage_mb' => $this->memoryUsage,
                'cpu_usage' => $this->cpuUsage,
                'php_version' => $this->phpVersion,
            ],
        ];
    }

    private function sanitizeData(array $data): array
    {
        $sensitiveKeys = ['password', 'token', 'api_key', 'secret', 'private_key'];

        array_walk_recursive($data, function (&$value, $key) use ($sensitiveKeys) {
            if (in_array(strtolower($key), $sensitiveKeys)) {
                $value = '[REDACTED]';
            }
        });

        return $data;
    }
}
```

**Key Enhancements**:
1. ✅ Unified context (Domain + Request + System)
2. ✅ Replaces both ExceptionContext and ErrorHandlerContext
3. ✅ Factory methods for different context types
4. ✅ Fluent API preserved and extended
5. ✅ Automatic data sanitization

### 2.3 Enhanced ErrorCode with Severity Mapping

**File**: `src/Framework/Exception/Core/ErrorCode.php`

```php
<?php

declare(strict_types=1);

namespace App\Framework\Exception\Core;

enum ErrorCode: string
{
    // ... (alle bestehenden 100+ ErrorCodes bleiben)

    // NEW: Severity mapping
    public function getSeverity(): ErrorSeverity
    {
        return match($this) {
            // CRITICAL Severity
            self::SYSTEM_RESOURCE_EXHAUSTED,
            self::DB_CONNECTION_FAILED,
            self::DB_POOL_EXHAUSTED,
            self::SEC_SQL_INJECTION_ATTEMPT,
            self::SEC_XSS_ATTEMPT,
            self::SEC_PATH_TRAVERSAL_ATTEMPT,
            self::PERF_MEMORY_LIMIT_EXCEEDED,
            self::PERF_CIRCUIT_BREAKER_OPEN,
            self::FS_DISK_FULL => ErrorSeverity::CRITICAL,

            // ERROR Severity
            self::SYSTEM_DEPENDENCY_MISSING,
            self::DB_QUERY_FAILED,
            self::DB_TRANSACTION_FAILED,
            self::DB_MIGRATION_FAILED,
            self::AUTH_CREDENTIALS_INVALID,
            self::AUTH_INSUFFICIENT_PRIVILEGES,
            self::CACHE_CONNECTION_FAILED,
            self::FS_FILE_NOT_FOUND,
            self::FS_PERMISSION_DENIED,
            self::API_SERVICE_UNAVAILABLE,
            self::QUEUE_CONNECTION_FAILED,
            self::QUEUE_JOB_FAILED,
            self::PERF_EXECUTION_TIMEOUT,
            self::EVENT_DISPATCH_FAILED,
            self::TPL_RENDERING_FAILED => ErrorSeverity::ERROR,

            // WARNING Severity
            self::SYSTEM_CONFIG_INVALID,
            self::DB_CONSTRAINT_VIOLATION,
            self::AUTH_TOKEN_EXPIRED,
            self::AUTH_SESSION_EXPIRED,
            self::HTTP_RATE_LIMIT_EXCEEDED,
            self::API_RATE_LIMIT_EXCEEDED,
            self::CACHE_KEY_NOT_FOUND,
            self::QUEUE_MAX_RETRIES_EXCEEDED,
            self::PERF_THRESHOLD_EXCEEDED,
            self::TPL_TEMPLATE_NOT_FOUND => ErrorSeverity::WARNING,

            // INFO Severity
            self::HTTP_NOT_FOUND,
            self::ENTITY_NOT_FOUND,
            self::VAL_REQUIRED_FIELD_MISSING,
            self::VAL_INVALID_FORMAT,
            self::VAL_OUT_OF_RANGE => ErrorSeverity::INFO,

            // DEBUG Severity
            self::DISC_CACHE_CORRUPTION,
            self::TPL_CACHE_FAILED => ErrorSeverity::DEBUG,

            // Default to ERROR for unmapped codes
            default => ErrorSeverity::ERROR,
        };
    }

    // Existing methods remain unchanged
    public function getCategory(): string { ... }
    public function getNumericCode(): int { ... }
    public function getDescription(): string { ... }
    public function getRecoveryHint(): string { ... }
    public function isRecoverable(): bool { ... }
    public function getRetryAfterSeconds(): ?int { ... }
}
```

**Key Enhancements**:
1. ✅ `getSeverity()` method mapping all 100+ codes to severities
2. ✅ Explicit severity for each category
3. ✅ Fallback to ERROR for unmapped codes

### 2.4 Integrated ErrorHandler

**File**: `src/Framework/Exception/Handler/ErrorHandler.php`

```php
<?php

declare(strict_types=1);

namespace App\Framework\Exception\Handler;

use App\Framework\Exception\Aggregation\ErrorAggregator;
use App\Framework\Exception\Core\FrameworkException;
use App\Framework\Exception\Reporting\ErrorReporter;
use App\Framework\Http\Response;
use Throwable;

/**
 * Integrated ErrorHandler with automatic aggregation and reporting
 */
final readonly class ErrorHandler
{
    public function __construct(
        private ErrorLogger $logger,
        private ResponseFactory $responseFactory,
        private ContextBuilder $contextBuilder,
        private ErrorAggregator $aggregator,      // NEW: Auto-integrated
        private ErrorReporter $reporter,          // NEW: Auto-integrated
        private bool $enableAggregation = true,
        private bool $enableReporting = true,
    ) {
    }

    /**
     * Register global error handlers
     */
    public function register(): void
    {
        set_exception_handler($this->handleException(...));
        set_error_handler($this->handleError(...));
        register_shutdown_function($this->handleShutdown(...));
    }

    /**
     * Handle exception with automatic integration
     */
    public function handleException(Throwable $exception): void
    {
        try {
            // 1. Build unified context
            $context = $this->contextBuilder->buildFromException($exception);

            // 2. Enrich FrameworkException with full context
            if ($exception instanceof FrameworkException) {
                $exception = $this->enrichException($exception, $context);
            }

            // 3. Log the exception
            $this->logger->logException($exception, $context);

            // 4. Auto-trigger aggregation (if enabled and not skipped)
            if ($this->enableAggregation && !$this->shouldSkipAggregation($exception)) {
                $this->aggregator->processException($exception, $context);
            }

            // 5. Auto-trigger reporting (if enabled and not skipped)
            if ($this->enableReporting && !$this->shouldSkipReporting($exception)) {
                $this->reporter->reportException($exception, $context);
            }

            // 6. Create HTTP response (only if in HTTP context)
            if ($this->isHttpContext()) {
                $response = $this->responseFactory->createFromException($exception, $context);
                $this->emitResponse($response);
            }

        } catch (Throwable $e) {
            // Fallback: Don't let error handling crash the application
            $this->handleErrorHandlerFailure($e, $exception);
        }
    }

    /**
     * Enrich FrameworkException with full context
     */
    private function enrichException(
        FrameworkException $exception,
        ExceptionContext $fullContext
    ): FrameworkException {
        // Only enrich if exception doesn't already have full context
        if ($fullContext->requestId && !$exception->getContext()->requestId) {
            return $exception->withContext($fullContext);
        }

        return $exception;
    }

    /**
     * Check if aggregation should be skipped
     */
    private function shouldSkipAggregation(Throwable $exception): bool
    {
        if ($exception instanceof FrameworkException) {
            return $exception->shouldSkipAggregation();
        }

        return false;
    }

    /**
     * Check if reporting should be skipped
     */
    private function shouldSkipReporting(Throwable $exception): bool
    {
        if ($exception instanceof FrameworkException) {
            return $exception->shouldSkipReporting() || $exception->isReported();
        }

        return false;
    }

    /**
     * Create HTTP response from exception
     */
    public function createHttpResponse(
        Throwable $exception,
        ?ExceptionContext $context = null
    ): Response {
        $context ??= $this->contextBuilder->buildFromException($exception);
        return $this->responseFactory->createFromException($exception, $context);
    }

    // ... (rest of existing ErrorHandler methods)
}
```

**Key Enhancements**:
1. ✅ Automatic ErrorAggregator integration
2. ✅ Automatic ErrorReporter integration
3. ✅ Respects `skipAggregation()` and `skipReporting()` flags
4. ✅ Prevents duplicate reporting via `isReported()` check
5. ✅ Graceful fallback if integration fails

### 2.5 Auto-Triggered ErrorAggregator

**File**: `src/Framework/Exception/Aggregation/ErrorAggregator.php`

```php
<?php

declare(strict_types=1);

namespace App\Framework\Exception\Aggregation;

use App\Framework\Exception\Core\ExceptionContext;
use App\Framework\Exception\Core\FrameworkException;
use Throwable;

/**
 * Auto-triggered ErrorAggregator (called by ErrorHandler)
 */
final readonly class ErrorAggregator
{
    // ... (existing constructor and properties)

    /**
     * NEW: Process exception (called by ErrorHandler)
     */
    public function processException(
        Throwable $exception,
        ExceptionContext $context
    ): void {
        try {
            // Create ErrorEvent from exception + context
            $errorEvent = ErrorEvent::fromException($exception, $context);

            // Use existing processErrorEvent logic
            $this->processErrorEvent($errorEvent);

        } catch (\Throwable $e) {
            // Don't let aggregation break the application
            $this->logError("Failed to process exception: " . $e->getMessage(), [
                'exception' => $e,
                'original_exception' => $exception->getMessage(),
            ]);
        }
    }

    /**
     * Existing: Process ErrorEvent
     */
    public function processErrorEvent(ErrorEvent $event): void
    {
        // Existing logic remains unchanged
        $this->storage->storeEvent($event);
        $pattern = $this->updateErrorPattern($event);

        if ($pattern->shouldAlert()) {
            $this->queueAlert($pattern, $event);
        }

        $this->logError("Error processed", [
            'event_id' => $event->id->toString(),
            'fingerprint' => $event->getFingerprint(),
            'pattern_id' => $pattern->id->toString(),
        ]);
    }

    // ... (rest of existing methods remain unchanged)
}
```

**Key Enhancements**:
1. ✅ New `processException()` method for ErrorHandler integration
2. ✅ Creates ErrorEvent from Throwable + ExceptionContext
3. ✅ Delegates to existing `processErrorEvent()` logic
4. ✅ Graceful error handling

### 2.6 Enhanced ErrorEvent

**File**: `src/Framework/Exception/Aggregation/ErrorEvent.php`

```php
<?php

declare(strict_types=1);

namespace App\Framework\Exception\Aggregation;

use App\Framework\Exception\Core\ExceptionContext;
use App\Framework\Exception\Core\FrameworkException;
use Throwable;

/**
 * Enhanced ErrorEvent with Throwable support
 */
final readonly class ErrorEvent
{
    // ... (existing properties remain)

    /**
     * NEW: Create from Throwable + ExceptionContext
     */
    public static function fromException(
        Throwable $exception,
        ExceptionContext $context
    ): self {
        // Extract ErrorCode (if FrameworkException)
        $errorCode = $exception instanceof FrameworkException
            ? $exception->getErrorCode() ?? self::inferErrorCode($exception)
            : self::inferErrorCode($exception);

        // Extract severity
        $severity = $exception instanceof FrameworkException
            ? $exception->getSeverity()
            : self::inferSeverity($exception);

        return new self(
            id: Ulid::generate(),
            service: self::extractServiceName($context),
            component: $context->component ?? 'unknown',
            operation: $context->operation ?? 'unknown',
            errorCode: $errorCode,
            errorMessage: $exception->getMessage(),
            severity: $severity,
            occurredAt: new \DateTimeImmutable(),
            context: $context->data,
            metadata: $context->metadata,
            requestId: $context->requestId,
            userId: $context->userId,
            clientIp: $context->clientIp,
            isSecurityEvent: self::isSecurityException($exception),
            stackTrace: $exception->getTraceAsString(),
            userAgent: $context->userAgent,
        );
    }

    /**
     * Existing: Create from ErrorHandlerContext (backward compatibility)
     */
    public static function fromErrorHandlerContext(ErrorHandlerContext $context): self
    {
        // Existing logic remains for backward compatibility during migration
        // Will be deprecated after migration complete
    }

    /**
     * Infer ErrorCode from generic Throwable
     */
    private static function inferErrorCode(Throwable $exception): ErrorCode
    {
        return match (true) {
            $exception instanceof \PDOException => ErrorCode::DB_QUERY_FAILED,
            $exception instanceof \RuntimeException => ErrorCode::SYSTEM_RESOURCE_EXHAUSTED,
            $exception instanceof \InvalidArgumentException => ErrorCode::VAL_INVALID_INPUT,
            default => ErrorCode::SYSTEM_RESOURCE_EXHAUSTED,
        };
    }

    /**
     * Infer severity from generic Throwable
     */
    private static function inferSeverity(Throwable $exception): ErrorSeverity
    {
        return match (true) {
            $exception instanceof \Error => ErrorSeverity::CRITICAL,
            $exception instanceof \PDOException => ErrorSeverity::ERROR,
            $exception instanceof \RuntimeException => ErrorSeverity::ERROR,
            default => ErrorSeverity::WARNING,
        };
    }

    /**
     * Check if exception is security-related
     */
    private static function isSecurityException(Throwable $exception): bool
    {
        if ($exception instanceof FrameworkException) {
            return $exception->isCategory('SEC');
        }

        return false;
    }

    // ... (rest of existing methods remain unchanged)
}
```

**Key Enhancements**:
1. ✅ New `fromException()` factory method
2. ✅ Automatic ErrorCode inference for non-FrameworkException
3. ✅ Automatic severity inference
4. ✅ Security exception detection
5. ✅ Backward compatibility with `fromErrorHandlerContext()`

## 3. Integration Architecture

### 3.1 Automatic Integration Flow

```
┌─────────────────────────────────────────────────────────────────┐
│ 1. Exception Thrown                                             │
│    throw FrameworkException::create(ErrorCode::DB_QUERY_FAILED) │
└──────────────────────┬──────────────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────────────┐
│ 2. ErrorHandler::handleException()                              │
│    - Build ExceptionContext (Domain + Request + System)         │
│    - Enrich FrameworkException with full context                │
│    - Log exception via ErrorLogger                              │
└──────────────────────┬──────────────────────────────────────────┘
                       │
        ┌──────────────┼──────────────┐
        │              │              │
        ▼              ▼              ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 3a. Aggregate│ │ 3b. Report   │ │ 3c. Respond  │
│ (async)      │ │ (async)      │ │ (sync)       │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
       │                │                │
       ▼                ▼                ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ ErrorEvent   │ │ ErrorReport  │ │ HTTP Response│
│ ErrorPattern │ │ Analytics    │ │ JSON/HTML    │
│ Alert Queue  │ │ Storage      │ │              │
└──────────────┘ └──────────────┘ └──────────────┘
```

### 3.2 ErrorBoundaries Integration

**File**: `src/Framework/Exception/Boundaries/Exceptions/BoundaryException.php`

```php
<?php

declare(strict_types=1);

namespace App\Framework\Exception\Boundaries\Exceptions;

use App\Framework\Exception\Core\ErrorCode;
use App\Framework\Exception\Core\FrameworkException;

/**
 * Base exception for ErrorBoundaries (extends FrameworkException)
 */
class BoundaryException extends FrameworkException
{
    public function __construct(
        string $message,
        string $boundaryName,
        ?\Throwable $previous = null
    ) {
        parent::__construct($message, 0, $previous);

        $this->withOperation('boundary.execute', 'ErrorBoundary')
            ->withData(['boundary_name' => $boundaryName])
            ->withErrorCode(ErrorCode::PERF_CIRCUIT_BREAKER_OPEN);
    }
}
```

**File**: `src/Framework/Exception/Boundaries/Exceptions/BoundaryTimeoutException.php`

```php
<?php

declare(strict_types=1);

namespace App\Framework\Exception\Boundaries\Exceptions;

use App\Framework\Exception\Core\ErrorCode;

final class BoundaryTimeoutException extends BoundaryException
{
    public function __construct(
        string $message,
        string $boundaryName,
        float $executionTimeSeconds,
        ?\Throwable $previous = null
    ) {
        parent::__construct($message, $boundaryName, $previous);

        $this->withData([
            'execution_time_seconds' => $executionTimeSeconds,
            'timeout_type' => 'boundary_timeout',
        ])->withErrorCode(ErrorCode::PERF_EXECUTION_TIMEOUT);
    }
}
```

**Key Changes**:
1. ✅ BoundaryException extends FrameworkException
2. ✅ Inherits ErrorCode, ExceptionContext, retry logic
3. ✅ Automatically integrated with ErrorHandler
4. ✅ Benefits from pattern detection and reporting

### 3.3 Database Schema Consolidation

**Migration**: `src/Framework/Exception/Migrations/CreateErrorEventsTable.php`

```php
<?php

use App\Framework\Database\Schema\Blueprint;
use App\Framework\Database\Schema\Schema;

return new class {
    public function up(Schema $schema): void
    {
        $schema->create('error_events', function (Blueprint $table) {
            // Primary key
            $table->string('id', 26)->primary(); // ULID

            // Domain context
            $table->string('service', 50);
            $table->string('component', 100);
            $table->string('operation', 100);
            $table->string('error_code', 20);
            $table->text('error_message');
            $table->string('severity', 20); // CRITICAL, ERROR, WARNING, INFO, DEBUG

            // Timing
            $table->timestamp('occurred_at');

            // Context data (JSON)
            $table->json('context')->nullable();
            $table->json('metadata')->nullable();

            // Request context
            $table->string('request_id', 50)->nullable();
            $table->string('user_id', 50)->nullable();
            $table->string('client_ip', 45)->nullable(); // IPv6 support
            $table->text('user_agent')->nullable();

            // Security
            $table->boolean('is_security_event')->default(false);

            // Debugging
            $table->text('stack_trace')->nullable();

            // NEW: Reporting fields (merged from error_reports)
            $table->string('report_level', 20)->nullable(); // error, warning, info, debug
            $table->json('environment')->nullable(); // System context
            $table->boolean('is_reported')->default(false);
            $table->timestamp('reported_at')->nullable();

            // Indexes for performance
            $table->index(['service', 'occurred_at']);
            $table->index(['error_code', 'occurred_at']);
            $table->index(['severity', 'occurred_at']);
            $table->index('request_id');
            $table->index('user_id');
            $table->index(['is_security_event', 'occurred_at']);
            $table->index('occurred_at'); // For cleanup queries
        });
    }

    public function down(Schema $schema): void
    {
        $schema->drop('error_events');
    }
};
```

**Migration**: `src/Framework/Exception/Migrations/CreateErrorPatternsTable.php`

```php
<?php

use App\Framework\Database\Schema\Blueprint;
use App\Framework\Database\Schema\Schema;

return new class {
    public function up(Schema $schema): void
    {
        $schema->create('error_patterns', function (Blueprint $table) {
            // Primary key
            $table->string('id', 26)->primary(); // ULID

            // Pattern identification
            $table->string('fingerprint', 64)->unique(); // SHA-256 hash

            // Pattern metadata
            $table->string('service', 50);
            $table->string('component', 100);
            $table->string('operation', 100);
            $table->string('error_code', 20);
            $table->text('normalized_message');
            $table->string('severity', 20);

            // Occurrence tracking
            $table->integer('occurrence_count')->default(1);
            $table->timestamp('first_occurrence');
            $table->timestamp('last_occurrence');

            // Impact tracking (JSON arrays)
            $table->json('affected_users')->nullable(); // Array of user IDs
            $table->json('affected_ips')->nullable(); // Array of IP addresses

            // Pattern lifecycle
            $table->boolean('is_active')->default(true);
            $table->boolean('is_acknowledged')->default(false);
            $table->string('acknowledged_by', 100)->nullable();
            $table->timestamp('acknowledged_at')->nullable();
            $table->text('resolution')->nullable();

            // Additional metadata
            $table->json('metadata')->nullable();

            // Timestamps
            $table->timestamp('created_at');
            $table->timestamp('updated_at');

            // Indexes for performance
            $table->index(['service', 'is_active', 'last_occurrence']);
            $table->index(['error_code', 'is_active']);
            $table->index(['severity', 'is_active', 'occurrence_count']);
            $table->index(['is_active', 'is_acknowledged']);
            $table->index('last_occurrence'); // For cleanup queries
        });
    }

    public function down(Schema $schema): void
    {
        $schema->drop('error_patterns');
    }
};
```

**Key Changes**:
1. ✅ Merged `error_reports` fields into `error_events`
2. ✅ Single source of truth für error storage
3. ✅ Optimized indexes for common queries
4. ✅ Retained all functionality from both tables

### 3.4 Backward Compatibility Strategy

**Compatibility Layer**: `src/Framework/Exception/Compatibility/ErrorHandlerContextAdapter.php`

```php
<?php

declare(strict_types=1);

namespace App\Framework\Exception\Compatibility;

use App\Framework\Exception\Core\ExceptionContext;

/**
 * Adapter for old ErrorHandlerContext (backward compatibility)
 *
 * @deprecated Will be removed in next major version
 */
final readonly class ErrorHandlerContextAdapter
{
    /**
     * Convert old ErrorHandlerContext to new ExceptionContext
     */
    public static function toExceptionContext($oldContext): ExceptionContext
    {
        // Map old context structure to new unified context
        return ExceptionContext::empty()
            ->withOperation(
                $oldContext->exception->operation ?? 'unknown',
                $oldContext->exception->component ?? 'unknown'
            )
            ->withData($oldContext->exception->data ?? [])
            ->withDebug($oldContext->exception->debug ?? [])
            ->withMetadata($oldContext->exception->metadata ?? [])
            ->withRequestContext(
                $oldContext->request->requestId ?? '',
                $oldContext->request->method ?? 'GET',
                $oldContext->request->requestUri ?? '/',
                $oldContext->request->clientIp ?? null,
                $oldContext->request->userAgent ?? null,
                $oldContext->request->userId ?? null
            )
            ->withSystemContext(
                $oldContext->system->environment ?? 'production',
                $oldContext->system->hostname ?? 'unknown',
                $oldContext->system->memoryUsageMb ?? 0.0,
                $oldContext->system->cpuUsage ?? 0.0
            );
    }
}
```

**Deprecation Notice**: `src/Framework/ErrorHandling/ErrorHandlerContext.php`

```php
<?php

namespace App\Framework\ErrorHandling;

/**
 * @deprecated Use \App\Framework\Exception\Core\ExceptionContext instead
 * Will be removed in next major version
 */
final readonly class ErrorHandlerContext
{
    // Keep existing implementation for backward compatibility
    // Add deprecation notice in constructor

    public function __construct(...)
    {
        trigger_error(
            'ErrorHandlerContext is deprecated. Use ExceptionContext instead.',
            E_USER_DEPRECATED
        );

        // ... existing constructor logic
    }
}
```

## 4. Performance Optimizations

### 4.1 Async Processing

**Queue Integration** for ErrorAggregation and ErrorReporting:

```php
// In ErrorHandler::handleException()
if ($this->enableAggregation && !$this->shouldSkipAggregation($exception)) {
    // Queue aggregation instead of synchronous processing
    $this->queue->push('error_aggregation', [
        'exception_class' => get_class($exception),
        'exception_data' => $exception->toArray(),
        'context' => $context->toArray(),
    ]);
}

if ($this->enableReporting && !$this->shouldSkipReporting($exception)) {
    // Queue reporting instead of synchronous processing
    $this->queue->push('error_reporting', [
        'exception_class' => get_class($exception),
        'exception_data' => $exception->toArray(),
        'context' => $context->toArray(),
    ]);
}
```

**Background Jobs**:
- `ProcessErrorAggregationJob` - Processes queued aggregation
- `ProcessErrorReportingJob` - Processes queued reports
- `CleanupExpiredErrorEventsJob` - Cleanup old error events

### 4.2 Caching Strategy

**Pattern Cache** (existing, enhanced):
```php
// Cache error patterns with fingerprint key
$cacheKey = 'error_pattern:' . $fingerprint;
$this->cache->remember($cacheKey, fn() => $pattern, Duration::fromHours(1));
```

**ErrorCode Severity Cache** (new):
```php
// Cache ErrorCode → ErrorSeverity mapping
private static array $severityCache = [];

public function getSeverity(): ErrorSeverity
{
    if (isset(self::$severityCache[$this->value])) {
        return self::$severityCache[$this->value];
    }

    $severity = match($this) { ... };
    self::$severityCache[$this->value] = $severity;

    return $severity;
}
```

### 4.3 Database Optimizations

**Batch Inserts** for error_events:
```php
// Batch insert instead of individual inserts
public function storeEventsBatch(array $events): void
{
    $data = array_map(fn($event) => $event->toArray(), $events);
    $this->db->table('error_events')->insert($data);
}
```

**Index Strategy**:
- Composite indexes for common query patterns
- Separate indexes for cleanup queries (by occurred_at)
- JSON column indexes for metadata searches (PostgreSQL)

**Partitioning** (future optimization):
- Partition error_events by occurred_at (monthly partitions)
- Automatic partition management
- Faster cleanup queries

## 5. Testing Strategy

### 5.1 Unit Tests

**Test Coverage Requirements**: ≥95% for all core components

**Priority Test Suites**:

1. **FrameworkExceptionTest.php**
   - Factory methods
   - Fluent API
   - Context enrichment
   - Severity mapping
   - Serialization

2. **ExceptionContextTest.php**
   - Factory methods
   - Fluent API for all context types
   - Data sanitization
   - Serialization

3. **ErrorCodeTest.php**
   - Severity mapping for all 100+ codes
   - Category extraction
   - Recovery hints
   - Retry timing

4. **ErrorHandlerTest.php**
   - Automatic aggregation
   - Automatic reporting
   - Skip flags
   - Backward compatibility

5. **ErrorAggregatorTest.php**
   - Pattern detection
   - Fingerprinting
   - Alert triggering
   - Batch processing

6. **ErrorBoundaryIntegrationTest.php**
   - BoundaryException extends FrameworkException
   - Automatic integration
   - Circuit breaker

### 5.2 Integration Tests

**End-to-End Error Flow**:
```php
it('handles exception end-to-end with automatic integration', function () {
    // 1. Throw exception
    $exception = FrameworkException::create(
        ErrorCode::DB_QUERY_FAILED,
        'Database query failed'
    );

    // 2. Error handler processes
    $this->errorHandler->handleException($exception);

    // 3. Verify aggregation triggered
    expect($this->queue)->toHaveJob('error_aggregation');

    // 4. Process aggregation job
    $this->processQueue('error_aggregation');

    // 5. Verify pattern created
    $patterns = $this->errorAggregator->getActivePatterns();
    expect($patterns)->toHaveCount(1);
    expect($patterns[0]->errorCode)->toBe('DB002');

    // 6. Verify reporting triggered
    expect($this->queue)->toHaveJob('error_reporting');

    // 7. Process reporting job
    $this->processQueue('error_reporting');

    // 8. Verify report created
    $reports = $this->errorReporter->getRecentReports();
    expect($reports)->toHaveCount(1);
});
```

### 5.3 Performance Tests

**Benchmarks**:
```php
it('creates exception in <1ms', function () {
    $start = microtime(true);

    $exception = FrameworkException::create(
        ErrorCode::DB_QUERY_FAILED,
        'Test exception'
    );

    $duration = (microtime(true) - $start) * 1000;
    expect($duration)->toBeLessThan(1.0);
});

it('processes 1000 errors in <5 seconds', function () {
    $start = microtime(true);

    for ($i = 0; $i < 1000; $i++) {
        $exception = FrameworkException::create(
            ErrorCode::DB_QUERY_FAILED,
            "Error {$i}"
        );
        $this->errorHandler->handleException($exception);
    }

    $duration = microtime(true) - $start;
    expect($duration)->toBeLessThan(5.0);
});
```

## 6. Migration Checklist

### Phase 1: Core Infrastructure
- [ ] Create new Exception/ directory structure
- [ ] Implement enhanced FrameworkException
- [ ] Implement unified ExceptionContext
- [ ] Enhance ErrorCode with severity mapping
- [ ] Create ErrorSeverity enum
- [ ] Write unit tests for core components

### Phase 2: Handler Integration
- [ ] Implement integrated ErrorHandler
- [ ] Create ContextBuilder
- [ ] Create ResponseFactory
- [ ] Implement async queue integration
- [ ] Write integration tests

### Phase 3: Aggregation Integration
- [ ] Enhance ErrorAggregator with processException()
- [ ] Enhance ErrorEvent with fromException()
- [ ] Update ErrorPattern (no changes needed)
- [ ] Migrate database schema
- [ ] Write aggregation tests

### Phase 4: Reporting Integration
- [ ] Enhance ErrorReporter with reportException()
- [ ] Merge ErrorReport with ErrorEvent
- [ ] Update AnalyticsEngine
- [ ] Write reporting tests

### Phase 5: Boundaries Integration
- [ ] Create BoundaryException extending FrameworkException
- [ ] Update BoundaryTimeoutException
- [ ] Update BoundaryFailedException
- [ ] Update ErrorBoundary to use new exceptions
- [ ] Write boundaries integration tests

### Phase 6: Backward Compatibility
- [ ] Create ErrorHandlerContextAdapter
- [ ] Add deprecation notices
- [ ] Update documentation
- [ ] Create migration guide

### Phase 7: Cleanup
- [ ] Remove old ErrorHandling/ directory
- [ ] Remove old ErrorAggregation/ directory
- [ ] Remove old ErrorBoundaries/ directory
- [ ] Remove old ErrorReporting/ directory
- [ ] Update all imports across codebase

## 7. Success Metrics

### Before
- ❌ 4 separate error modules
- ❌ Manual integration required
- ❌ 3 database tables
- ❌ Fragmented context
- ❌ Inconsistent exception types
- ❌ ~2.000 lines across modules

### After
- ✅ 1 unified Exception module
- ✅ Automatic integration
- ✅ 2 database tables (consolidated)
- ✅ Unified ExceptionContext
- ✅ All exceptions extend FrameworkException
- ✅ ~2.500 lines (enhanced functionality)
- ✅ <1ms exception creation
- ✅ <5ms pattern detection (async)
- ✅ <10ms error reporting (async)

## 8. Next Steps

1. **Review & Approval** - Review this design document
2. **Migration Plan** - Create detailed step-by-step migration plan
3. **Prototyping** - Build proof-of-concept for critical components
4. **Testing Strategy** - Define comprehensive test suite
5. **Implementation** - Execute migration in phases
6. **Documentation** - Update all framework documentation
7. **Release** - Plan major version release

---

**Status**: Design Phase Complete ✅
**Next Document**: `ERROR-HANDLING-MIGRATION-PLAN.md`
**Estimated Implementation**: 3-5 days
