Recent changes RSS feed
 

Error Handling

This document describes error handling with the WACT framework, but much of this advise is applicable to PHP applications in general.

Configuration Settings

PHP has many configuration options that influence error handling behavior. See PHP Error Handling and Logging Functions for a complete list.

Many PHP error configuration settings only work correctly and fully if set outside of the PHP script environment.

Configuration settings for error handling must be treated differently in the production and development environments. Error reporting requirements are higher in the development environment. Development oriented error reporting should not be used on production servers.

Production

The following error configuration settings are recommended for your production server. You may want to place these settings in a .htaccess file for your application. This way, the application will continue to perform as expected, even if the httpd.conf or php.ini files are altered, or if the application is installed on a server with an unknown configuration.

See the section on configuration settings in Writing Portable PHP Code for more information about where and how to set configuration settings.

Hiding Errors from the user

These settings prevent PHP‘s default error handler from showing error messages to the user.

php_flag display_errors off
php_flag display_startup_errors off

Hiding error messages can prevent internal application messages from revealing information to the user.

Logging errors

The following configuration setting directs PHP‘s default error handler to record error messages to an error log. This can help to track down the cause of any problems.

php_flag log_errors on

You may wish to specify a separate log file for your application.

php_value error_log /path/to/log

This can make it easier to work with an external log monitoring program, or expose the log in the application administration section in order to reveal errors which occur on a production system.

PHP errors which cause the termination of the apache process will not be directed to this log, but instead will be recorded in the apache error log and must be monitored separately.

Error Reporting

PHP‘s default error handler uses the error_reporting configuration setting to determine which errors to display (if display_errors is on) or to log (if log_errors is on). Many user error handlers will also respect the error_reporting configuration setting.

The error suppression operator @ temporarily lowers the error_reporting setting to 0. The current setting can be read with the error_reporting function.

In a production environment with the recommended log_errors set to on and display_errors set to off, the error_reporting setting controls which errors are written to the log file.

A higher error_reporting setting is generally better. However, cramming the log with messages that will be ignored is not helpful. Choosing the right error_reporting level means balancing these tradeoffs. Some 3rd party libraries may require lower error_reporting levels.

Remember, that error_reporting in the http.conf, .htaccess, or php.ini level only affects errors that have not been suppressed by the error suppression operator @, suppressed by a custom error handler via set_error_handler, or suppressed by setting error_reporting() within the application (temporarily or permanently). It may be better to suppress expected messages with one of these techniques, rather than with a global setting that might also hide unexpected messages.

Errors of type E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, and E_COMPILE_WARNING are uncatchable. They cannot be handled via a user level error handler within a PHP script. Thus, the only way to know if these errors have occurred in a program running on a production server is to set an error_reporting value that includes these types and to examine the error log.

The E_RECOVERABLE_ERROR is catchable, but if a user error handler is not installed and the error is not caught, the script is terminated. You may wish to include E_RECOVERABLE_ERROR in your error_reporting.

Common error_reporting levels:

# E_ALL
php_value error_reporting W

# E_ALL | E_STRICT
php_value error_reporting X

# E_ALL ^ E_NOTICE
php_value error_reporting Y

# E_ALL ^ E_NOTICE ^ E_WARNING
php_value error_reporting Z

WACT is intended to work correctly with any reporting_level.

Tracking Errors

With the error_tracking configuration setting on, php will record the message of any error condition that occurs in the variable $php_errormsg. The $php_errormsg variable retains its value until the next error occurs or until it goes out of scope. $php_errormsg will not be set if a user error handler has been registered with set_error_handler.

php_flag track_errors on

Sample benchmarks show that setting track_errors to off produces a negligible performance improvement. There is little measurable performance impact to leaving this setting on. Obviously, the more errors that occur in your program, the greater the impact of this setting. Reducing the number of errors that occur has an order of magnitude more impact on the performance of error handling than this configuration setting.

You may wish to set the track_errors configuration on a local level for portability or maintenance reasons. See Writing Portable PHP Code.

The message stored in $php_errormsg is influenced by configuration options controlling message display, such as html_errors.

WACT does not require that track_errors be on.

Formatting Error messages

Several configuration settings control the formatting of PHP error messages. html_errors, docref_ext and docref_root control the formatting of “docref” error messages. These effect the messages written to log files, passed to user error handlers, and placed in the $php_errormsg variable. It is recommended to disable this formatting on production machines.

php_flag html_errors off
php_value docref_ext 0 // correct?
php_value docref_root 0 // correct?

The error_append_string and error_prepend_string configuration settings control the formatting of error messages displayed by PHP‘s default error handler. They have no effect on logged messages, $php_errormsg, or any user error handlers. They have no effect if display_errors is off.

The log_errors_max_len controls the maximum length of any error messages logged or displayed by PHP‘s default error handler. The error message is truncated if it exceeds the specified length, unless the length is 0, in which case, the full error message is always used. Despite its name, this configuration setting effects errors that are displayed as well as errors that are logged.

The xmlrpc_errors and xml_rpc_error_number configuration settings are documented as part of the xmlrpc extension, however, they are a part of core PHP. These settings are available even if the extension is disabled. These configuration settings direct PHP‘s default error handler to generate an xmlrpc representation of the error message.

What is the impact of these settings on exception messages?

Repeated Errors

The ignore_repeated_errors and ignore_repeated_source configuration settings direct PHP‘s default error handler not to display or log an error message if it is the same as the last error message that occurred. (Regardless of whether that message was displayed or logged). These settings can also suppress the assignment of $php_errormsg for “non-docref” style errors.

Using these settings on a production server is not recommended.

php_value_flag ignore_repeated_error off

Instead, suppress the error messages. (see section XXX)

Fatal Errors

The E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILER_ERROR error types are fatal. This means that execution of the running PHP script is halted at the point at which the error occurs.

The user may see a blank page, or incomplete output. Pending Output Buffering callbacks and register_shutdown_functions are still called even when a fatal error has occurred.

Is there a way to issue a non-blank 500 style error page for a PHP fatal error?

Monitoring Log Files

Recommendations

Development

The following error configuration settings are recommended for the php.ini file for your development environment:

display_errors = On
display_startup_errors = On
error_reporting = E_ALL | E_STRICT

Working with PHP Errors

From time to time, PHP detects that an error condition has occurred. These conditions can be of varying severity from ignorable to fatal. PHP classifies each error condition into one of several error types.

PHP‘s error handling functions are described in the Error Handling and Logging Functions section of the PHP manual.

WACT does not use the PHP Error mechanism. However, most built-in PHP functions do, and other third party libraries may use this capability. Therefore, WACT does provide some tools for working with PHP errors.

Global Error Handling

When a PHP Error occurs, the global callback assigned with set_error_handler is called. This callback handler can perform some sort of action. After the callback handler completes, execution continues from the point where the error occurs. (Unless the callback handler halts the program.)

A global callback handler has very little context specific information at its disposal. As a result, there is very little that a global error handler can do in response to an error.

One possibility to to log the error. Unless you have very special logging needs, you may want to leave the global error handler undefined and allow the built-in php logging mechanisms to handle this task, as explained in the section on PHP configuration options.

In a debugging environment, you may wish to augment the standard PHP error messages with additional debugging information. WACT provides an error handler for this purpose.

require_once 'wact/exception/debughandler.inc.php';
 
$handler = new WactDebugExceptionHandler();
$handler->install();

The install method on WactDebugExceptionHandler will call set_error_handler for you. You may also call the uninstall method to remove the handler object.

Suppressing Error Conditions

PHP can detect many error conditions. Some of these conditions might not even be considered errors at all. It is often necessary to suppress or ignore the error conditions that PHP discovers.

We don’t want to fill up the error log with expected or unimportant messages.

Suppressing error conditions with error_reporting()

PHP maintains a global setting which indicates which types of errors should be ignored. See Error Reporting. The error_reporting function allows you to change the error_reporting configuration option in your program. You can do this to temporarily suppress certain kinds of errors.

$oldErrorReporting = error_reporting(E_NONE);
// Do something that might trigger an expected or unimportant error message
error_reporting($oldErrorReporting);

The error still occurs and the error handler callback is still called, however PHP‘s built-in error handler and most custom error handlers check the error_reporting setting.

The error suppression operator (@)

see Error Control Operator in the PHP Manual. The error suppression operator works by temporarily setting error_reporting to E_NONE and then restoring the value when the operation has completed.

The scope of error suppression

Be careful with error_reporting and the error suppression operator. Calling functions while these operators are active can lead to suppressing unexpected as well as expected errors. For example:

@some_function(some_other_function());

In this code, if an error occurs while executing some_other_function, that error will be suppressed. This can be very hard to debug. If the intent here is only to supress the errors from some_function, this code should be re-written as:

$result = some_other_function();
@some_function($result);

Unexpected errors that occur while errors are being suppressed are difficult to track down. It can be easy to suppress errors for a broader scope than you might intend.

Don't suppress real errors

Defensive Code

It can sometimes be better to defensively check for an error causing condition, rather than allowing the condition to occur and then suppressing the error. For example:

$x = isset($var) ? $var : NULL;

instead of

$x = @$var;

Defensive codling prevents suppressing too many errors.

Reacting to Errors

There are three ways to react in context to an error that has occurred. One is to check the $php_errormsg. The other is to use an error handler that converts errors into exceptions, the third is to use a local error handler.

Checking for errors with $php_errormsg

Local error handlers

Converting errors into exceptions

Triggering your own Errors

Don’t.

Using a Custom Error Handler

Writing an error handler

Working with Exceptions

See Exceptions in the PHP Manual.

Catching Exceptions

Wrapping Exceptions

Collecting Exceptions

Raising Exceptions

Testing Exceptions

Using a Custom Exception Handler

Writing an exception handler

References

 
wact/error_handling.txt · Last modified: 2007/04/22 16:28 by jeff_moore
 
Hosting for this site donated by Procata PHP Development