This article will describe how you can handle and control errors on your web applications. When errors occur this means that the application has encountered something unexpected. These can be a innocent and easy to correct, but others can severely compromise your server's security if not corrected and addressed properly. By default, everyone should NOT be showing error messages to the public on a production web server. With some simple Apache configurations this can easily be implemented. Below are a few Apache configurations that you could set. Either set this in httpd.conf, vhost.conf or if server permissions are allowed, can also be set in a .htaccess file under the web root.
php_flag log_errors On
php_value error_reporting 2047
php_flag track_errors On
php_flag track_vars On
php_admin_value display_errors Off
This by itself will just present the user with a white screen, which is not ideal to the user's experience. What this article will teach is how to set up error handling that will catch the error, send the user to a 'Error' page and email you the error along with variable information that might help aide in debugging the problem.
To do this, we're going to focus on set_error_handler() function. PHP.net defines it:
This function can be used for defining your own way of handling errors during runtime, for example in applications in which you need to do cleanup of data/files when a critical error happens, or when you need to trigger an error under certain conditions (using trigger_error()).
Now, we're basically dealing with two types of errors. One is runtime error and the other is user defined error. SQL connection problems can be treated as user defined error, and I'll show how to use the trigger_error() function mentioned above.
To manage errors, we need to create a new function and pass that to set_error_handler(). Create a new function called errHandle() and include this in your application. Ideally you'll have a global include so all your pages will be able to see set_error_handler() and errHandle().
<?
// custom error handler
function errHandle($errno, $msg, $filename, $linenum, $vars){
$type = array(
1 => "Error",
2 => "Warning",
4 => "Parsing Error",
8 => "Notice",
16 => "Core Error",
32 => "Core Warning",
64 => "Compile Error",
128 => "Compile Warning",
256 => "User Error",
512 => "User Warning",
1024=> "User Notice");
$dt = date("Y-m-d H:i:s (T)");
$severityFlag = 0;
switch($type[$errno]){ // Check the type of error and act appropriately
case "Warning":
case "User Warning":
case "Parsing Error":
case "Error":
case "Notice":
case "User Error":
$errMessage = $dt . " " . $type[$errno] . ": " . $filename . " on line " . $linenum . "n" . $msg . "nnn";
// Loop through the vars array and write out all of the values.
$keys = array_keys($vars);
$varList = parseVars($vars, $keys, "");
for($x = sizeof($varList); $x > -1; --$x){
if(isset($varList[$x])){
$errMessage .= htmlspecialchars($varList[$x]);
}
}
@ob_end_clean();
mail("support@yourdomain.com", "YourDomain.com Web site Error Notification", $errMessage, "From: YourDomain.com Public Error<support@yourdomain.com>n");
include($vars["rootpath"] . "ErrorPage.php");
exit();
}
}
// This function loops through the array of variables in the erroneous page and inserts all necessary ones into an array.
function parseVars($vars, $keys, $currentKey){
$newVars = array(); // an array of variables with undesirables parsed out
for($i = 0; $i < sizeof($vars); $i++){
$keys = array_keys($vars);
$dontParse = array("GLOBALS", "_ENV", "HTTP_ENV_VARS", "PASSWORD", "DBNAME", "DBUSER", "DBPASSWORD", "KEYVAL", "IV");
// Check to see if the variable is an array
if(!(in_array(strtoupper($keys[$i]), $dontParse))){
if(is_array($vars[$keys[$i]])){
$keyList = array_keys($vars[$keys[$i]]);
if($currentKey != ""){
$varList = parseVars($vars[$keys[$i]], $keyList, $currentKey . "[" . $keys[$i] . "]");
} else{
$varList = parseVars($vars[$keys[$i]], $keyList, "$" . $keys[$i]);
}
$newVars = array_merge($newVars, $varList);
}else{
if($currentKey != "")
$newVars[sizeof($newVars)] = $currentKey . "[" . $keys[$i] . "] = " . $vars[$keys[$i]] . "n";
else
$newVars[sizeof($newVars)] = "$" . $keys[$i] . " = " . $vars[$keys[$i]] . "n";
}
}
}
return $newVars;
}
?>
This function will take the error message along with all the variables from the user that triggered the error and email all information to you. After this information is handled, it will include your custom error page, letting them know that there was a problem, etc.
To let the application know about this, you'll need to define the set_error_handler. This needs to be declared on every page, or in a globally included file.
set_error_handler("errHandle");
This will catch all runtime errors, but if you wanted to catch SQL errors you'll need to trigger it. Below is an example of using trigger_error() on a MySQL query.
$sql = "SELECT *
FROM table
WHERE ID = '".mysql_real_escape_string($_GET["ID"])."'
AND Active = 1
LIMIT 1";
if(!$rs = mysql_query($sql,$connect)){
trigger_error(sprintf("SQL Error: %d: %sn" , mysql_errno(), mysql_error()), E_USER_ERROR);
}
There are many ways to skin this cat, hopefully this will get you thinking about error management in the future!
Thanks!
Go Back
|
Critical Errors Andrew Wells | 01/14/07 at 8:34PM This method will not catch a critical error. For example, if you call the function crash();, it would be a critical error, and the script will stop w/o even calling any exit methods. Are there any methods that will trap fatal/critical errors? |
|
I wonder how you do this? julieismetoo | 02/16/07 at 09:54AM Hello! Wow, I've found the same to be true too! Where did you get that at? Bye, - MyGirl! P.S. How do you minimize SPAM on your comments? |
|
Diuqy Diuqy | 05/09/07 at 8:53PM Keep up the great work! |
