|
|
|
|
@ -11,9 +11,6 @@ if (! defined('BaseDir')) { |
|
|
|
|
define('LOG_FILE', BaseDir . '/protected/logs/error_log.txt'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (! defined('ENVIRONMENT')) { |
|
|
|
|
define('ENVIRONMENT', 'production'); // 'production' or 'development' |
|
|
|
|
} |
|
|
|
|
/** |
|
|
|
|
* Format message with appropriate colors based on environment |
|
|
|
|
*/ |
|
|
|
|
@ -82,11 +79,18 @@ set_error_handler(function($errno, $errstr, $errfile, $errline) { |
|
|
|
|
file_put_contents(LOG_FILE, $logMessage, FILE_APPEND); |
|
|
|
|
} |
|
|
|
|
// Display in development environment |
|
|
|
|
if (ENVIRONMENT === 'development') { |
|
|
|
|
if (fallback_dev()) { |
|
|
|
|
echo formatMessage($displayMessage, $errorCategory); |
|
|
|
|
// Prevent PHP's default error handler |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Prevent PHP's default error handler |
|
|
|
|
if (is_on_error_page() === true) { |
|
|
|
|
if (fallback_requires('prod_error.php') === false) { |
|
|
|
|
fallback_requires('views/on_error/prod_error.php', true); |
|
|
|
|
} |
|
|
|
|
exit(1); // Prevent HTML Looping!!! |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
@ -101,7 +105,8 @@ set_exception_handler(function($e) { |
|
|
|
|
if (LOG_FILE !== false) { |
|
|
|
|
file_put_contents(LOG_FILE, $logMessage, FILE_APPEND); |
|
|
|
|
} |
|
|
|
|
if (ENVIRONMENT === 'development') { |
|
|
|
|
// Are we developing...? if so, show details on error |
|
|
|
|
if (fallback_dev()) { |
|
|
|
|
echo formatMessage($displayMessage, 'error'); |
|
|
|
|
} else { |
|
|
|
|
// In production, show user-friendly message |
|
|
|
|
@ -124,12 +129,151 @@ register_shutdown_function(function() { |
|
|
|
|
if (LOG_FILE !== false) { |
|
|
|
|
file_put_contents(LOG_FILE, $logMessage, FILE_APPEND); |
|
|
|
|
} |
|
|
|
|
if (ENVIRONMENT === 'development') { |
|
|
|
|
// If developing, show error |
|
|
|
|
if (fallback_dev()) { |
|
|
|
|
echo formatMessage($displayMessage, 'error'); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
function fallback_is_live(): bool { |
|
|
|
|
return is_live(); // from main.php |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Displays Error page |
|
|
|
|
* @param type $ex error message |
|
|
|
|
*/ |
|
|
|
|
function broken_error($ex = ''): void { |
|
|
|
|
if (fallback_is_cli()) { |
|
|
|
|
echo $ex; |
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
$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); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (fallback_is_live()) { |
|
|
|
|
// Try really Hard to display Prod Error Page |
|
|
|
|
$exists = fallback_requires('prod_error.php'); |
|
|
|
|
if (! $exists) { |
|
|
|
|
$exists = fallback_requires('views/on_error/prod_error.php', true); |
|
|
|
|
} |
|
|
|
|
if ($exists === false) { |
|
|
|
|
echo "<h1>Sorry, we had an error...</h1><p>We apologize for any inconvenience this may cause.</p>"; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if ($ex === "") { |
|
|
|
|
echo "<h2>Unknown Issue...</h2>"; |
|
|
|
|
} else { |
|
|
|
|
echo $ex; |
|
|
|
|
} |
|
|
|
|
echo "<h1>Error Page</h1><p>Please go back to another page...</p>"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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); |
|
|
|
|
exit; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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 { |
|
|
|
|
return strtok($_SERVER['REQUEST_URI']); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function fallback_dev(): bool { |
|
|
|
|
if (! defined("ENVIRONMENT")) { |
|
|
|
|
return false; // Force Live on unknown state |
|
|
|
|
} |
|
|
|
|
if (ENVIRONMENT === 'development') { |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function fallback_requires(string $file, bool $fw = false): 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 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Check if already on Error Page |
|
|
|
|
* @return bool |
|
|
|
|
*/ |
|
|
|
|
function is_on_error_page(): bool { |
|
|
|
|
if (fallback_is_cli()) { |
|
|
|
|
exit(1); |
|
|
|
|
} else { |
|
|
|
|
return (stripos(fallback_get_uri(), "error.html") !== false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 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"); |
|
|
|
|
|