Expanding error handling with a custom handler. All errors are converted to exceptions for easier handling and to help save time because you won't have to type out a bunch of crazy sanity checks, just try/catch FTW.

This commit is contained in:
Josh Sherman 2010-09-19 12:27:55 -04:00
parent 17d5738e77
commit 4307594ab5
4 changed files with 105 additions and 27 deletions

View file

@ -44,9 +44,9 @@ class Controller extends Object
}
// Ack, not sure what page to load, throw an error
if (!isset($_REQUEST['request']) && $this->config->module['default'] == null)
if (!isset($_REQUEST['request']) && (empty($this->config->module['default']) || $this->config->module['default'] == null))
{
Error::fatal('Unable complete this request because no URI was specified and there is no default module specified in config.ini');
Error::fatal('Unable complete this request because no URI was provided and there is no default module specified in config.ini');
}
// Loads the requested module's information
if (isset($_REQUEST['request']) && trim($_REQUEST['request']) != '')

View file

@ -32,25 +32,66 @@ class Error extends Object
*/
public static function fatal($message)
{
if (Log::error($message) == false)
{
$message .= '<br /><br />This error message could not be logged as the log path or log file is not writable';
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Error - <?=$_SERVER['SERVER_NAME'];?></title>
<title><?php echo $_SERVER['SERVER_NAME']; ?> - error</title>
<style>
html{background:#eee;font-family:Verdana;width:100%}
body{background:#ff9c9c;padding:20px;-moz-border-radius:20px;-webkit-border-radius:20px;width:550px;margin:0 auto;margin-top:100px;text-align:center;border:3px solid #890f0f}
h1{font-size:1.5em;color:#600;text-shadow:#a86767 2px 2px 2px;margin:0}
html
{
background: #eee;
font-family: "Lucida Sans", "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, sans-serif;
width: 100%;
height: 100%;
font-size: 1em;
}
body
{
text-align: center;
margin-top: 100px;
}
div
{
font-size: 150%;
color: #600;
text-shadow: 2px 2px 2px #eb8383;
margin: 0;
font-weight: bold;
background: #ff9c9c;
padding: 20px;
border-radius: 20px;
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
width: 550px;
margin: 0 auto;
border: 3px solid #890f0f;
}
h1, a
{
font-size: 70%;
color: #999;
text-decoration: none;
}
a:hover
{
color: #000;
}
</style>
</head>
<body>
<h1><?=$message;?></h1>
<h1><?php echo $_SERVER['SERVER_NAME']; ?></h1>
<div><?php echo $message; ?></div>
<a href="http://phpwithpickles.com" target="_blank">Powered by PICKLES</a>
</body>
</html>
<?php
Log::error($message);
exit;
}

View file

@ -117,27 +117,34 @@ class Log extends Object
private static function write($log_type, $message, $format = true, $time = false)
{
$log_path = LOG_PATH . date('Y/m/d/', ($time == false ? time() : $time));
if (!file_exists($log_path))
try
{
mkdir($log_path, 0777, true);
if (!file_exists($log_path))
{
mkdir($log_path, 0755, true);
}
$log_file = $log_path . $log_type . '.log';
$message .= "\n";
if ($format == true)
{
$backtrace = debug_backtrace();
rsort($backtrace);
$frame = $backtrace[strpos($backtrace[0]['file'], 'index.php') === false ? 0 : 1];
return file_put_contents($log_file, date('H:i:s') . ' ' . str_replace(getcwd(), '', $frame['file']) . ':' . $frame['line'] . ' ' . $message, FILE_APPEND);
}
else
{
return file_put_contents($log_file, $message, FILE_APPEND);
}
}
$log_file = $log_path . $log_type . '.log';
$message .= "\n";
if ($format == true)
catch (ErrorException $exception)
{
$backtrace = debug_backtrace();
rsort($backtrace);
$frame = $backtrace[strpos($backtrace[0]['file'], 'index.php') === false ? 0 : 1];
return file_put_contents($log_file, date('H:i:s') . ' ' . str_replace(getcwd(), '', $frame['file']) . ':' . $frame['line'] . ' ' . $message, FILE_APPEND);
}
else
{
return file_put_contents($log_file, $message, FILE_APPEND);
return false;
}
}
}

View file

@ -26,6 +26,9 @@
ini_set('display_errors', true);
error_reporting(E_ALL | E_STRICT);
// Sets the error handler
set_error_handler('__handleError');
// @todo Allow users to override the timezone from their configuration file.
// Sets the timezone to avoid Smarty warnings
if (ini_get('date.timezone') == '')
@ -95,4 +98,31 @@ function __autoload($class)
return $loaded;
}
/**
* Error handling function that thinks it's magical
*
* Catches errors (warnings and the like) and throws it back out as an
* ErrorException. This really helps trapping complex errors that need a ton of
* sanity checks, just try / catch and you're good. Also, this isn't a magic
* function, but I opted to use the __ prefix to help avoid a naming collision
* since namespace support is 5.3+ and PICKLES strives to be 5.0+ compatible.
*
* @param integer $number error number
* @param string $string error string (message)
* @param string $file name of the file with the error
* @param integer $line line number the error occurred on
* @param array $context variables that were in play
* @return ErrorException not really returned, but worth documenting
*/
function __handleError($number, $string, $file, $line, array $context)
{
// Handle hacktastic @ error suppression. Seriously, don't ever use @
if (error_reporting() === 0)
{
return false;
}
throw new ErrorException($string, 0, $number, $file, $line);
}
?>