rfc:enhanced_error_handling

This is an old revision of the document!


Request for Comments: Enhanced Error Handling

Introduction

php_error(), zend_throw_extension(), the @-operator... PHP and/or the Zend Engine respectively offer a variety of error issuance and handling mechanisms. There is, however, no encompassing concepts: Core functions only issue php_errors (suppressable), intl 1.0.3 by default suppresses all errors but can activate php_errors, pdo however has a proprietary flag to define error behaviour that allows exceptions - but limits php_error to E_WARNING.

I state that error handling has to be in the hands of the user (php coder). Some may prefer php_error()s, others prefer exceptions; some are ok with E_WARNINGs that indicate severe situations, others prefer E_ERROR for those cases; and some might want to either suppress all messages or default to a big exception block per script in production systems.

Scope

Error conditions are encountered in a variety of places and cases. This RFC only covers error conditions in a running script, e.g. a file was not found.

All other situations - like compilation problems, core errors in engine startup/shutdown - are out of scope.

Definitions

Error Behaviours

If an error condition is met, different types of reactions are possible:

Name Description
Suppress Note down error and return an error value, e.g. false/NULL
Error same as Suppress, but issue a php_error as well
Throw same as Suppress, but throw an exception as well

The error behaviour should be configurable by the user; preferably system-wide and overridable. An extension should not, however, decide to differ from the user's wishes.

In any case, there should be a method to get at the noted-down error information, e.g. error code and message.

Error Parameters

php_error needs an E_* value to distinguish warnings and errors and the Throw behaviour needs an exception class.

Defaults for those parameters should be configurable like the error behaviour. The extension should however be able, while issuing an error, to set appropriate parameters if necessary.

For extreme cases - like “one big exception block per script” - the default parameters should be enforcable by the user's wishes.

Error Container Hierarchy

PHP lives of its extensibility. An extension can offer a whole bunch of different classes that are related; take intl as an example. It could be interesting for the user to differentiate his error reactions by object and/or extension. He could wish to let the whole of intl throw a PersonalIntlExceptionClass upon errors or decide to switch to exceptions for a long block of translation calls (not testing each and every result on its own) while he usually prefers E_ERRORS being issued.

The proposal therefore stands for a three-level hierarchy:

Level Description
Global Define behaviour and default parameters
Could be used to force behaviour as well as parameters, eg. in production
Field/Extension Inherits from Global level
Overrides behaviour and parameters for a “field”, e.g. all i18n in intl.so
Object Inherits from Field level
Overrides behaviour and parameters for a single object

If any level enforces behaviour and/or parameters, the lower levels will not deviate.

Special Cases

Enforced Exception class

Each level could enforce the use of a specific exception class, e.g. PersonalIntlExceptionClass() for all of intl.so. While forcing such a common class does ease catching, some information a more specific class could provide is lost.

As of PHP 5.3, the concept of exception chaining has been introduced, whereas a “previous” extension can be attached. In order to keep the previously lost information, the concrete exception class given upon issuing an error should be chained to the enforced class.

Notices

Notices are issued en masse all over PHP - even for plain language constructs like array access. They are regularly ignored on production systems and seldomly indicate errors. I like to compare them to warnings of a compiler, indicating that something could go wrong here (php does issue them at runtime, not compile-time).

Whereas an user could decide to downgrade every error to a notice in this concept, actual notices should be issued the same way as before.

@-Operator

The @ operator does suppress error issuance for the evaluation of the expression it is prepended to. It does so - currently - completely for php_error()s, not however for exceptions.

If possible, the operator should be limited to errors in the execution of scripts but “silence” thrown exceptions as well (like a “per object” Suppress above). It's functionality should be prohibited, if a certain behaviour is enforced.

Backwards Compatibility

Extensions

Extensions can keep backwards compatibility, if their current default behaviour is mapped to the above-mentioned Field level. Even special cases should be representable with the mentioned behaviours, parameters and enforcement.

Core

I would personally not touch the core, but it's error behaviour should be representable as well.

Proposal and Patch

An intl extension-level implementation is being created by kampfcaspar at https://saintcyr.oeri.ch/trac/php-intl/

Changelog

Date Author Message
2009-12-27 kampfcaspar Created Initial Version
rfc/enhanced_error_handling.1261941129.txt.gz · Last modified: 2017/09/22 13:28 (external edit)