routeConfigs = array_merge($this->getDefaultRouteConfigs(), $routeConfigs); } /** * Create error boundary for specific route */ public function createForRoute(string $routeName): ErrorBoundary { $config = $this->getConfigForRoute($routeName); return $this->create("route_{$routeName}", $config); } /** * Create error boundary for database operations */ public function createForDatabase(string $operation = 'database'): ErrorBoundary { return $this->create($operation, BoundaryConfig::database()); } /** * Create error boundary for external service calls */ public function createForExternalService(string $serviceName): ErrorBoundary { return $this->create("external_{$serviceName}", BoundaryConfig::externalService()); } /** * Create error boundary for UI components */ public function createForUI(string $componentName): ErrorBoundary { return $this->create("ui_{$componentName}", BoundaryConfig::ui()); } /** * Create error boundary for background jobs */ public function createForBackgroundJob(string $jobName): ErrorBoundary { return $this->create("job_{$jobName}", BoundaryConfig::backgroundJob()); } /** * Create error boundary for critical operations */ public function createForCriticalOperation(string $operationName): ErrorBoundary { return $this->create("critical_{$operationName}", BoundaryConfig::critical()); } /** * Create custom error boundary */ public function create(string $name, BoundaryConfig $config): ErrorBoundary { $circuitBreakerManager = null; if ($config->circuitBreakerEnabled && $this->stateManagerFactory) { $stateManager = $this->stateManagerFactory->createForErrorBoundary(); $circuitBreakerManager = new BoundaryCircuitBreakerManager($stateManager, $this->logger); } $eventPublisher = new BoundaryEventPublisher($this->eventBus, $this->logger); return new ErrorBoundary( boundaryName: $name, config: $config, timer: $this->timer ?? new SystemTimer(), logger: $this->logger, circuitBreakerManager: $circuitBreakerManager, eventPublisher: $eventPublisher, errorAggregator: $this->errorAggregator, contextProvider: $this->contextProvider, ); } private function getConfigForRoute(string $routeName): BoundaryConfig { // Check for exact route match if (isset($this->routeConfigs[$routeName])) { return $this->routeConfigs[$routeName]; } // Check for pattern matches foreach ($this->routeConfigs as $pattern => $config) { if (str_contains($pattern, '*') && $this->matchesPattern($routeName, $pattern)) { return $config; } } // Default configuration return $this->routeConfigs['default']; } private function matchesPattern(string $routeName, string $pattern): bool { $regex = str_replace('*', '.*', preg_quote($pattern, '/')); return (bool) preg_match("/^{$regex}$/", $routeName); } private function getDefaultRouteConfigs(): array { return [ // API routes - more retries and circuit breaker 'api/*' => BoundaryConfig::externalService(), // Admin routes - critical operations 'admin/*' => BoundaryConfig::critical(), // Auth routes - fail fast for security 'auth/*' => BoundaryConfig::failFast(), // Public routes - user-friendly defaults 'public/*' => BoundaryConfig::ui(), // Background job routes 'job/*' => BoundaryConfig::backgroundJob(), // Database operations 'db/*' => BoundaryConfig::database(), // Default fallback 'default' => new BoundaryConfig( maxRetries: 2, retryStrategy: RetryStrategy::EXPONENTIAL_JITTER, baseDelay: Duration::fromMilliseconds(100), maxDelay: Duration::fromSeconds(2), circuitBreakerEnabled: true, circuitBreakerThreshold: 5, circuitBreakerTimeout: Duration::fromMinutes(1), enableMetrics: true ), // HTTP request fallback 'http_request' => new BoundaryConfig( maxRetries: 1, retryStrategy: RetryStrategy::FIXED, baseDelay: Duration::fromMilliseconds(50), maxDelay: Duration::fromMilliseconds(200), circuitBreakerEnabled: false, enableMetrics: true ), ]; } }