page_output = $msg; if (fallback_requires($file, false, $mini) === false) { fallback_requires("views/on_error/" . $file, true, $mini); } // If you really must close all of your output buffers except one, this'll do it: while (ob_get_level() > $saved_ob_level) { ob_end_flush(); } return @ob_get_clean(); } function fallback_logger(string $logMessage, string $file = LOG_FILE) { if (method_exists("CodeHydrater\services\log", "write")) { $logger = new \CodeHydrater\services\log("errors"); $written = $logger->write($logMessage); if ($written === false) { // Open a connection to the system logger openlog("PHP App", LOG_PID | LOG_ODELAY, LOG_LOCAL0); // Write a message syslog(LOG_INFO, $logMessage); // Close the connection closelog(); } } else { $Message = date('[Y-m-d H:i:s]') . $logMessage; file_put_contents($file, $Message, FILE_APPEND); } } /** * Format message with appropriate colors based on environment */ function formatMessage($message, $type = 'error') { if (PHP_SAPI === 'cli') { // CLI color formatting $colors = [ 'error' => "\033[31m", // red 'warning' => "\033[33m", // yellow 'notice' => "\033[36m", // cyan 'reset' => "\033[0m" // reset ]; $color = $colors[$type] ?? $colors['error']; $message = wordwrap($message, WORD_WRAP_CHRS, "\n"); return $color . $message . $colors['reset'] . PHP_EOL; } else { // Web HTML formatting $styles = [ 'error' => 'uk-alert-danger', 'warning' => 'uk-alert-warning', 'notice' => 'uk-alert-primary' ]; $style = $styles[$type] ?? $styles['error']; $message = wordwrap($message, WORD_WRAP_CHRS, "
\n"); $assets = "/assets/uikit/css/uikit.gradient.min.css"; if (file_exists(BaseDir. "/public/" . $assets)) { $msg = ''; $msg .= "
"; } else { $msg = "
['ERROR', 'error'], E_WARNING => ['WARNING', 'warning'], E_PARSE => ['PARSE ERROR', 'error'], E_NOTICE => ['NOTICE', 'notice'], E_CORE_ERROR => ['CORE ERROR', 'error'], E_CORE_WARNING => ['CORE WARNING', 'warning'], E_COMPILE_ERROR => ['COMPILE ERROR', 'error'], E_COMPILE_WARNING => ['COMPILE WARNING', 'warning'], E_USER_ERROR => ['USER ERROR', 'error'], E_USER_WARNING => ['USER WARNING', 'warning'], E_USER_NOTICE => ['USER NOTICE', 'notice'], E_STRICT => ['STRICT', 'notice'], E_RECOVERABLE_ERROR=> ['RECOVERABLE ERROR', 'error'], E_DEPRECATED => ['DEPRECATED', 'warning'], E_USER_DEPRECATED => ['USER DEPRECATED', 'warning'] ]; $errorInfo = $errorTypes[$errno] ?? ['UNKNOWN', 'error']; $errorType = $errorInfo[0]; $errorCategory = $errorInfo[1]; $logMessage = " [$errorType] $errstr in $errfile on line $errline" . PHP_EOL; $displayMessage = "$errorType: $errstr in $errfile on line $errline"; fallback_logger($logMessage); // Display in development environment if (fallback_dev()) { echo fallback_mini_view_dev(formatMessage($displayMessage, $errorCategory)); // Prevent PHP's default error handler return true; } should_be_broken($displayMessage); return true; }); // Handle exceptions set_exception_handler(function($e) { if (method_exists("errors", "get_handle_exceptions") && ! errors::get_handle_exceptions()) { return false; } $logMessage = " [EXCEPTION] " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine() . PHP_EOL; $displayMessage = "UNCAUGHT EXCEPTION: " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine(); fallback_logger($logMessage); // Are we developing...? if so, show details on error if (fallback_dev()) { echo fallback_mini_view_dev(formatMessage($displayMessage, 'error')); } else { if (should_be_broken($displayMessage) === false) { // In production, show user-friendly message echo PHP_SAPI === 'cli' ? "An error occurred. Our team has been notified." . PHP_EOL : "An error occurred. Our team has been notified."; } } }); // Handle fatal errors register_shutdown_function(function() { if (method_exists("errors", "get_handle_global_errors") && ! errors::get_handle_global_errors()) { return false; } $error = error_get_last(); if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) { $logMessage = " [FATAL] {$error['message']} in {$error['file']} on line {$error['line']}" . PHP_EOL; $displayMessage = "FATAL ERROR: {$error['message']} in {$error['file']} on line {$error['line']}"; fallback_logger($logMessage); // If developing, show error if (fallback_dev()) { echo fallback_mini_view_dev(formatMessage($displayMessage, 'error')); } else { should_be_broken($displayMessage); } } }); /** * Displays Error page * @param type $ex error message */ function broken_error(string $ex = "", bool $clear = false): void { if (fallback_is_cli()) { echo $ex; return; } $use_api = fallback_is_api(); if ($use_api === true) { $internal_error = "An unexpected error occured."; $status_code = 500; fallback_json_error($internal_error, $status_code); return; } $error_message = "

Sorry, we had an error...

We apologize for any inconvenience this may cause.

"; if ($clear === false) { echo $error_message; } else { echo fallback_mini_view_prod($error_message); } } function fallback_json_error(string $data, int $status_code): void { if (!headers_sent()) { header($_SERVER['SERVER_PROTOCOL'] . " " . $status_code); /* * Allow JavaScript from anywhere. CORS - Cross Origin Resource Sharing * @link https://manning-content.s3.amazonaws.com/download/f/54fa960-332e-4a8c-8e7f-1eb213831e5a/CORS_ch01.pdf */ header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Methods: *"); header('Content-Type: application/json; charset=utf-8', true, intval($status_code)); } echo json_encode($data); } function fallback_is_api(): bool { $uri = fallback_get_uri(); if (preg_match('~/api(\d*)/~', $uri)) { return true; } return false; } function fallback_is_cli() { if (defined('STDIN')) { return true; } if (php_sapi_name() === 'cli') { return true; } if (array_key_exists('SHELL', $_ENV)) { return true; } if (!isset($_SERVER['REMOTE_ADDR']) && !isset($_SERVER['HTTP_USER_AGENT'])) { return true; } if (!array_key_exists('REQUEST_METHOD', $_SERVER)) { return true; } return false; } function fallback_get_uri(): ?string { $uri = strtok($_SERVER['REQUEST_URI'], "?"); if ($uri === false) { return ""; } return $uri; } function fallback_requires(string $file, bool $fw = false, $local = null): bool { $exists = method_exists("\CodeHydrater\bootstrap\requires", "secure_include"); if ($exists) { if ($fw === false) { $path = UseDir::ONERROR; } else { $path = UseDir::FRAMEWORK; } $good = \CodeHydrater\bootstrap\requires::secure_include($file, $path); return ($good === false) ? false : true; // handle contents vs. failure = false } else { if ($fw === false) { $view = CodeHydrater_PROJECT . "views/on_error/" . $file; } else { $view = CodeHydrater_FRAMEWORK . $file; } if (file_exists($view)) { include $view; return true; } } return false; // You have failed me for the last time! LOL } // Test the error handler (uncomment to test) // trigger_error("This is a test warning", E_USER_WARNING); // throw new Exception("This is a test exception"); // nonexistentFunction(); // Will trigger a fatal error in shutdown handler