NAME error_handling - RSX framework error handling patterns and shouldnt_happen() SYNOPSIS Error handling philosophy, fail-loud patterns, and sanity check functions DESCRIPTION The RSX framework enforces strict error handling that prioritizes early detection and clear failure over silent continuation. This document covers error handling patterns, the shouldnt_happen() function, and examples of proper failure handling in security-critical and framework contexts. CORE PHILOSOPHY Fail Loud, Not Silent: - Errors must be immediately apparent during development - No silent fallbacks or alternative code paths - Exception handlers should ONLY format error display, not provide alternatives - One deterministic way to do things No Defensive Coding for Core Classes: - Core framework classes in /app/RSpade/Core/ are ALWAYS present - Never check if core classes exist: if (typeof Rsx_Manifest !== 'undefined') - Just use them directly: Rsx_Manifest.define() - The build system guarantees core classes are present SHOULDNT_HAPPEN() FUNCTION Purpose: Explicitly fail when encountering "impossible" conditions that indicate broken assumptions or corrupted application state. When to Use: - After loading files, if expected classes don't exist - When required files are missing after checking they should exist - When database operations return unexpected null values - When array keys that must exist are missing - Any time you write a comment like "this shouldn't happen" - When critical resources fail to initialize - When configuration validation fails in unexpected ways PHP Usage Examples: // Class loading validation if (!class_exists($expected_class)) { shouldnt_happen("Class {$expected_class} should have been loaded in Phase 3"); } // File system validation if (!file_exists($required_file)) { shouldnt_happen("Required config file missing: {$required_file}"); } // Database state validation $user = User::find($user_id); if (!$user && $user_id > 0) { shouldnt_happen("User ID {$user_id} should exist based on session data"); } // Array key validation if (!isset($config['required_setting'])) { shouldnt_happen("Config missing required_setting after validation"); } // Resource initialization if (!$this->manifest_data) { shouldnt_happen("Manifest data not loaded after successful build"); } JavaScript Usage Examples: // DOM element validation if (!element) { shouldnt_happen(`Required DOM element #${elementId} not found`); } // API response validation if (!data.requiredField) { shouldnt_happen('API response missing required field: requiredField'); } // Framework state validation if (!Rsx._initialized) { shouldnt_happen('Rsx framework not initialized before use'); } // Component validation if (!this.template_rendered) { shouldnt_happen('Component ready() called before template render'); } SECURITY-CRITICAL ERROR HANDLING Never Continue on Security Failures: Security validation must fail loudly. Never provide fallback paths that could compromise security. String Sanitization Example: // ❌ CATASTROPHIC - Silent security failure try { $clean = Sanitizer::sanitize($user_input); } catch (Exception $e) { $clean = $user_input; // DISASTER - unsanitized data continues } // ✅ CORRECT - Fail loudly on security failure $clean = Sanitizer::sanitize($user_input); // Let it throw if it fails Authentication Example: // ❌ BAD - Silent fallback to unauthenticated try { $user = Auth::validateToken($token); } catch (Exception $e) { $user = null; // Dangerous - proceeds without authentication } // ✅ GOOD - Fail loudly on auth failure $user = Auth::validateToken($token); // Let it throw if invalid Authorization Example: // ❌ BAD - Silent permission failure if (!$user->hasPermission('admin')) { // Log error but continue anyway Log::error('Permission denied'); return $default_view; // WRONG - shows content without permission } // ✅ GOOD - Fail loudly on permission failure if (!$user->hasPermission('admin')) { throw new UnauthorizedException('Admin access required'); } FRAMEWORK ERROR PATTERNS No Alternative Code Paths: The framework should have ONE deterministic way to do things. No redundant fallback systems. Examples of Anti-Patterns: // ❌ BAD - Alternative fallback system try { $result = NewApiService::process($data); } catch (Exception $e) { $result = LegacyApiService::process($data); // WRONG } // ❌ BAD - Silent failure continuation if (!$critical_resource) { return; // WRONG - silent continue } // ❌ BAD - Defensive existence checks for core classes if (class_exists('Rsx_Manifest')) { Rsx_Manifest::register(); // WRONG - core classes always exist } Correct Patterns: // ✅ GOOD - Single path, fail loudly $result = NewApiService::process($data); // Let it throw // ✅ GOOD - Explicit failure on missing resources if (!$critical_resource) { shouldnt_happen("Critical resource not initialized"); } // ✅ GOOD - Direct usage of core classes Rsx_Manifest::register(); // Core classes guaranteed present EXCEPTION HANDLING GUIDELINES Exception Handlers Should Only Format: Exception handlers should format error display, not provide alternative functionality. Web Error Pages: // ✅ GOOD - Format error for user display try { return $controller->handle($request); } catch (Exception $e) { return view('errors.500', ['error' => $e->getMessage()]); } API Error Responses: // ✅ GOOD - Format error for API response try { $data = $service->processRequest($request); } catch (ValidationException $e) { return response()->json(['error' => $e->errors()], 422); } Development Error Display: // ✅ GOOD - Enhanced error display for development try { return $result; } catch (Exception $e) { if (config('app.debug')) { return $this->formatDevelopmentError($e); } throw $e; // Re-throw in production } DEBUGGING ERROR PATTERNS Use rsx_dump_die() for Development: Preferred debugging function that halts execution after output. Use liberally during debugging, remove after fixing issues. Examples: rsx_dump_die($user); // Debug single value rsx_dump_die($request, $params, $result); // Debug multiple values Never Hide Debugging Information: // ❌ BAD - Hidden debug information try { rsx_dump_die($debug_data); } catch (Exception $e) { // Silent ignore - WRONG } // ✅ GOOD - Let debug output show rsx_dump_die($debug_data); // Always visible VALIDATION ERROR HANDLING Input Validation: Input validation should throw exceptions immediately when validation fails. Never continue with invalid data. Model Validation: // ✅ GOOD - Fail on validation error $user = new User($data); $user->validate(); // Throws if invalid $user->save(); // ❌ BAD - Continue with invalid data $user = new User($data); if (!$user->validate()) { $user->email = 'default@example.com'; // WRONG } $user->save(); Configuration Validation: // ✅ GOOD - Fail on invalid config if (!config('app.key')) { shouldnt_happen('Application key not configured'); } // ❌ BAD - Default fallback config $key = config('app.key') ?: 'default-key'; // WRONG TESTING ERROR SCENARIOS Always Test the Failure Path: Ensure errors are visible and properly formatted during development. Error Testing Examples: // Test that exceptions are thrown $this->expectException(ValidationException::class); $service->processInvalidData($bad_data); // Test error message content try { $service->processData(null); $this->fail('Expected exception not thrown'); } catch (Exception $e) { $this->assertStringContains('Data cannot be null', $e->getMessage()); } // Test shouldnt_happen() scenarios try { $service->processWithMissingDependency(); $this->fail('shouldnt_happen not triggered'); } catch (RuntimeException $e) { $this->assertStringContains('shouldnt_happen', $e->getMessage()); } COMMON ANTI-PATTERNS TO AVOID Silent Continues: Never continue execution when critical operations fail. Redundant Systems: Never implement fallback systems that do the same thing differently. Defensive Core Checks: Never check if core framework classes exist. Security Fallbacks: Never provide fallback authentication or authorization. Default Values on Failure: Never substitute default values when validation fails. Try-Catch Workarounds: Never use try-catch to work around expected failures. SEE ALSO coding_standards - General coding conventions and standards console_debug - Debug output and filtering system config_rsx - Framework configuration patterns