rfc:enhanced_error_handling
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
rfc:enhanced_error_handling [2009/12/28 12:30] – Added draft API kampfcaspar | rfc:enhanced_error_handling [2010/01/10 16:19] – adjusted version/date kampfcaspar | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Request for Comments: Enhanced Error Handling ====== | ====== Request for Comments: Enhanced Error Handling ====== | ||
- | * Version: 0.1 | + | * Version: 0.5 |
- | * Date: | + | * Date: |
* Author: | * Author: | ||
* Status: | * Status: | ||
Line 8: | Line 8: | ||
===== Introduction ===== | ===== Introduction ===== | ||
- | php_error(), | + | php_error(), |
- | I state that error behaviour has to be in the hands of the user (php coder). | + | I think that error behaviour has to be in the hands of the user (php coder). |
- | ===== Scope ===== | + | ==== 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. | 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/ | All other situations - like compilation problems, core errors in engine startup/ | ||
+ | |||
+ | ==== Differences Observed ==== | ||
+ | |||
+ | * Almost all error behaviours include a human readable //error message// and a machine readable //error code//; the ' | ||
+ | * Error codes - if used - do not follow any //common semantic rules// and are therefore not interpretable without knowing their source; even more, they might be defined externally (SQLSTATE or linked library). | ||
+ | * While traditionally error numbers have mostly been numeric, also // | ||
+ | * Error codes and - to a lesser extent - error messages are traditionally held in a special variable or place for later inspection. Information held there may be reset //upon request/new error// (errno in C, error_get_last in PHP) or with any subsequent // | ||
+ | * There may be just a //single holding space// for later inspection of error information (error_get_last), | ||
+ | * Functions not bailing out on error situations should return a //defined error value//. There is, however, a variety of defined error values - also dependent on the required valid return value range, which might include values that other functions use as error indicating value. | ||
+ | * Definition of error actions - as described in the introduction - is handled by //php.ini// or //object calls// or //not available// at all. None of it offers all options. | ||
+ | |||
+ | |||
+ | ===== Goals ===== | ||
+ | |||
+ | The goal would be to create a framework in which | ||
+ | * the //PHP user// decides, what kind of error reaction he wishes; that includes | ||
+ | * having a single //error call// that abstracts away from zend_errors/ | ||
+ | * a minimal // | ||
+ | * offers a //C-level API// for compiled extensions as well as a //PHP-level API// for frameworks in that language. | ||
+ | * can be used in //OOP// as well as //non-OOP// situations. | ||
+ | |||
+ | |||
+ | Such goals can only be achieved under the side condition of //complete backwards compatibility// | ||
+ | existing php and extensions must not be changed - all existing error behaviour must be mappable. | ||
===== Definitions ===== | ===== Definitions ===== | ||
- | ==== Error Behaviours | + | ==== Error Actions |
If an error condition is met, different types of reactions are possible: | If an error condition is met, different types of reactions are possible: | ||
^ Name ^ Description | ^ Name ^ Description | ||
| Suppress | | Suppress | ||
+ | | Monitor | ||
| Error | same as Suppress, but issue a php_error as well | | | Error | same as Suppress, but issue a php_error as well | | ||
| Throw | same as Suppress, but throw an exception as well | | | Throw | same as Suppress, but throw an exception as well | | ||
- | The error behaviour | + | The error action |
- | 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, | + | Noted-down error information, |
- | error code and message. | + | |
+ | ==== Error Levels ==== | ||
+ | |||
+ | Existing extensions use their error mechanisms not only to issue grave errors, but also to | ||
+ | transport mere " | ||
+ | both an //error// and a //warning// call should be supplied. The latter - ignoring all configuration - | ||
+ | choosing Suppress or Monitor as appropraiate action. | ||
==== Error Parameters ==== | ==== Error Parameters ==== | ||
- | php_error | + | Different behaviours, ask for different additional parameters: |
+ | zend_error | ||
needs an exception class. | needs an exception class. | ||
- | Defaults | + | Default values |
- | should however be able, while issuing an error, to set appropriate parameters if necessary. | + | values |
- | + | error call itself. | |
- | For extreme cases - like "one big exception block per script" | + | |
- | should be enforcable by the user's wishes. | + | |
==== Error Container Hierarchy ==== | ==== Error Container Hierarchy ==== | ||
- | PHP lives of its extensibility. | + | PHP lives of its extensibility. |
- | that are related; take '' | + | default error behaviours. It goes without saying, that error behaviour must |
- | to differentiate his error reactions | + | keep being configurable //by extension//. |
- | He could wish to let the whole of '' | + | |
- | 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: | + | As some extensions currently do, I propose to add a layer of error |
+ | configurability on // | ||
+ | default to the extension' | ||
- | ^ Level ^ Description ^ | + | Without any hassle, // |
- | | Global | + | a PDO connection could be inherited its PDOStatements. |
- | | | 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 " | + | |
- | | Object | + | |
- | | | Overrides behaviour and parameters for a single object | | + | |
- | + | ||
- | If any level enforces behaviour and/or parameters, the lower levels will not deviate. | + | |
===== Special Cases ===== | ===== Special Cases ===== | ||
Line 70: | Line 91: | ||
==== Enforced Exception class ==== | ==== 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. | + | A lower hierarchy |
As of PHP 5.3, the concept of exception chaining has been introduced, whereas a " | As of PHP 5.3, the concept of exception chaining has been introduced, whereas a " | ||
Line 86: | Line 107: | ||
If possible, the operator should be limited to errors in the execution of scripts but " | If possible, the operator should be limited to errors in the execution of scripts but " | ||
- | ===== Implementation | + | ===== C API ===== |
+ | |||
+ | The following does not represent compilable code. | ||
==== Error Container ==== | ==== Error Container ==== | ||
- | Each level mentioned above would need storage for error parameters | + | The levels |
+ | configuration | ||
+ | by extensions as well as objects. | ||
<code c> | <code c> | ||
- | struct | + | struct |
- | // identification | + | |
- | | + | |
+ | error_container *delegate; | ||
- | // used to propagate errors up/down | + | |
- | | + | |
- | | + | |
- | | + | |
- | enum error_behaviour behaviour; | + | |
- | zend_bool | + | |
- | long | + | |
- | char * | + | |
- | zend_bool | + | |
- | + | ||
- | | + | |
- | char *container; | + | |
- | long code; | + | |
- | char *msg; | + | |
} | } | ||
</ | </ | ||
- | |||
- | * **name**\\ There would be a global container (probably NULL), per extension (extension name) and per object (" | ||
- | * **parent**\\ Used to create the hierarchy of containers, e.g. to force a behaviour to lower containers | ||
- | * **delegate**\\ Rather than copying error data two or even three times, set a pointer to the real data (container' | ||
- | * **behaviour**\\ Some enum for the behaviours mentioned above | ||
- | * **force-* **\\ Do force either behaviour or parameters for this container and children | ||
- | * **level**\\ Either default or forced error level (E_*) for zend_error() | ||
- | * **exception**\\ Either default or forced exception name (name instead of ce ptr allows to autoload) | ||
- | * **container**\\ In which container the error did occur (for user presentation) | ||
- | * **code** / **msg**\\ The usual error parameters | ||
==== Error Function ==== | ==== Error Function ==== | ||
<code c> | <code c> | ||
- | | + | |
+ | error_behaviour error_yellf( error_container *container, long level, char *exception, long code, char *format, ... ); | ||
</ | </ | ||
- | Each use of the error function should nevertheless be followed by a defined | + | Instead |
+ | error behaviour. It does, however | ||
- | ==== User API ==== | + | As errors might be suppressed, after the use of error_yell a defined return value should be returned to PHP. |
+ | One //cannot// be sure that the engine will branch away into an error or exception handler. | ||
- | < | + | ==== Utility functions === |
- | int error_get_code( [string|object] ); | + | |
- | string error_get_message( [string|object] ); | + | |
- | string error_get_origin( [string|object] ); | + | |
- | void | + | Apart from the error issuing function, several utility functions are needed, e.g.: |
- | | + | * Creation/ |
- | | + | * Setting/ |
- | | + | |
+ | * Clearing error incidents | ||
+ | |||
+ | The corresponding API depends too much on implementation detais to discuss those here. | ||
+ | |||
+ | ===== PHP API ===== | ||
+ | |||
+ | Apart from extensions in C, php code itself could use such unified error configuration as well. | ||
+ | Above mentioned error_yell function as well as utility functions to configure error actions and | ||
+ | read error information should be available. | ||
+ | |||
+ | A standard ErrorClass - implementing an object | ||
+ | level error container plus standardized methods to access it - should be available: | ||
+ | |||
+ | <code php> | ||
+ | class ErrorClass { | ||
+ | function __construct( | ||
+ | function setErrorAction(...); | ||
+ | | ||
+ | | ||
+ | function getLastError(); | ||
+ | } | ||
</ | </ | ||
- | A container should | + | Of course, the internal ErrorClass could be used as base class for |
+ | extension | ||
- | ==== Integration ==== | + | Error containers would be identified by: |
+ | * NULL: global/ | ||
+ | * string: extension-level container (e.g. in a hash) | ||
+ | * ErrorClass: object-level container | ||
- | Short of extending core structures of the Zend Engine and for better backwards compatibility, | + | In order to allow PHP frameworks |
+ | such a string-identified container | ||
===== Backwards Compatibility ===== | ===== Backwards Compatibility ===== | ||
Line 155: | Line 188: | ||
==== Extensions ==== | ==== Extensions ==== | ||
- | Extensions can keep backwards compatibility, | + | Extensions can keep backwards compatibility, |
==== Core ==== | ==== Core ==== | ||
- | I would personally not touch the core, but it's error behaviour | + | The core should |
===== Course of Action and Patch ===== | ===== Course of Action and Patch ===== | ||
- | - An intl extension-level implementation is being created by kampfcaspar at https:// | + | - Development: |
- Given enough feedback and operating experience, the enhanced error handling could be bundled in an "error extension" | - Given enough feedback and operating experience, the enhanced error handling could be bundled in an "error extension" | ||
- Other extensions could use the "error extension" | - Other extensions could use the "error extension" | ||
Line 172: | Line 205: | ||
| 2009-12-27 | | 2009-12-27 | ||
| 2009-12-28 | | 2009-12-28 | ||
+ | | 2010-01-07 | ||
+ | | 2010-01-10 |
rfc/enhanced_error_handling.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1