logger = VLogger::getInstance(); // Determine if we're in production mode global $cfg; $this->isProduction = !isset($cfg['debug_mode']) || !$cfg['debug_mode']; // Register error handlers $this->registerHandlers(); } /** * Register all error handlers */ private function registerHandlers() { // Set error handler for PHP errors set_error_handler([$this, 'handleError']); // Set exception handler for uncaught exceptions set_exception_handler([$this, 'handleException']); // Set shutdown handler for fatal errors register_shutdown_function([$this, 'handleShutdown']); // Set error reporting level if ($this->isProduction) { error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT); ini_set('display_errors', 0); ini_set('log_errors', 1); } else { error_reporting(E_ALL); ini_set('display_errors', 1); } } /** * Handle PHP errors */ public function handleError($severity, $message, $file, $line, $context = []) { // Don't handle errors that are suppressed with @ if (!(error_reporting() & $severity)) { return false; } $errorType = $this->getErrorType($severity); $logLevel = $this->getLogLevel($severity); $errorContext = [ 'error_type' => $errorType, 'severity' => $severity, 'file' => $file, 'line' => $line, 'context' => $context ]; $errorMessage = "{$errorType}: {$message} in {$file} on line {$line}"; $this->logger->log($logLevel, $errorMessage, $errorContext); // Don't execute PHP internal error handler return true; } /** * Handle uncaught exceptions */ public function handleException($exception) { $errorContext = [ 'exception_class' => get_class($exception), 'file' => $exception->getFile(), 'line' => $exception->getLine(), 'trace' => $exception->getTraceAsString(), 'previous' => $exception->getPrevious() ? $exception->getPrevious()->getMessage() : null ]; $errorMessage = "Uncaught Exception: " . $exception->getMessage() . " in " . $exception->getFile() . " on line " . $exception->getLine(); $this->logger->critical($errorMessage, $errorContext); // Show user-friendly error page in production if ($this->isProduction) { $this->showErrorPage('An unexpected error occurred. Please try again later.'); } else { $this->showDebugError($exception); } } /** * Handle fatal errors during shutdown */ public function handleShutdown() { $error = error_get_last(); if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) { $errorType = $this->getErrorType($error['type']); $errorContext = [ 'error_type' => $errorType, 'severity' => $error['type'], 'file' => $error['file'], 'line' => $error['line'] ]; $errorMessage = "Fatal Error: {$error['message']} in {$error['file']} on line {$error['line']}"; $this->logger->critical($errorMessage, $errorContext); // Show error page for fatal errors if ($this->isProduction) { $this->showErrorPage('A critical error occurred. Please contact support.'); } } } /** * Get error type string from severity level */ private function getErrorType($severity) { $errorTypes = [ E_ERROR => 'Fatal Error', E_WARNING => 'Warning', E_PARSE => 'Parse Error', E_NOTICE => 'Notice', E_CORE_ERROR => 'Core Error', E_CORE_WARNING => 'Core Warning', E_COMPILE_ERROR => 'Compile Error', E_COMPILE_WARNING => 'Compile Warning', E_USER_ERROR => 'User Error', E_USER_WARNING => 'User Warning', E_USER_NOTICE => 'User Notice', E_STRICT => 'Strict Standards', E_RECOVERABLE_ERROR => 'Recoverable Error', E_DEPRECATED => 'Deprecated', E_USER_DEPRECATED => 'User Deprecated' ]; return $errorTypes[$severity] ?? 'Unknown Error'; } /** * Get log level from error severity */ private function getLogLevel($severity) { switch ($severity) { case E_ERROR: case E_PARSE: case E_CORE_ERROR: case E_COMPILE_ERROR: case E_USER_ERROR: case E_RECOVERABLE_ERROR: return VLogger::ERROR; case E_WARNING: case E_CORE_WARNING: case E_COMPILE_WARNING: case E_USER_WARNING: return VLogger::WARNING; case E_NOTICE: case E_USER_NOTICE: case E_STRICT: return VLogger::NOTICE; case E_DEPRECATED: case E_USER_DEPRECATED: return VLogger::INFO; default: return VLogger::ERROR; } } /** * Show user-friendly error page */ private function showErrorPage($message) { // Clear any output buffer if (ob_get_level()) { ob_clean(); } http_response_code(500); // Try to use existing error template if (file_exists('error.php')) { include 'error.php'; } else { // Fallback error page echo $this->getErrorPageHTML($message); } exit; } /** * Show debug error information */ private function showDebugError($exception) { if (ob_get_level()) { ob_clean(); } http_response_code(500); echo $this->getDebugErrorHTML($exception); exit; } /** * Get error page HTML */ private function getErrorPageHTML($message) { return '
Message:
File: ' . htmlspecialchars($exception->getFile()) . ':' . $exception->getLine() . '
' . htmlspecialchars($trace) . '