diff options
author | Marcus Boerger <helly@php.net> | 2008-07-13 21:42:49 +0000 |
---|---|---|
committer | Marcus Boerger <helly@php.net> | 2008-07-13 21:42:49 +0000 |
commit | 2bf3bfc746f0f034ef9c443ae697b0c3f4b5d3dc (patch) | |
tree | d6fd38b7a2043f56906e1f10de7b445c13e6668a /Zend/zend_exceptions.c | |
parent | 805f552cd3e0be81a254f27abba64f27140f9c66 (diff) | |
download | php-git-2bf3bfc746f0f034ef9c443ae697b0c3f4b5d3dc.tar.gz |
- MFH Exception handling
[DOC]
- Exceptions can be thrown while exceptions are pending, they are linked
- Exceptions can be handled in __destruct
- Add optional Exception $previous parameter to
. Exception::__construct
. ErrorException::__construct
Diffstat (limited to 'Zend/zend_exceptions.c')
-rw-r--r-- | Zend/zend_exceptions.c | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 3c5f9c67e2..f71b53db70 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -33,13 +33,37 @@ zend_class_entry *error_exception_ce; static zend_object_handlers default_exception_handlers; ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC); +void zend_exception_set_previous(zval *add_previous TSRMLS_DC) +{ + zval *exception = EG(exception), *previous; + + if (exception == add_previous || !add_previous) { + return; + } + if (Z_TYPE_P(add_previous) != IS_OBJECT && !instanceof_function(Z_OBJCE_P(add_previous), default_exception_ce TSRMLS_CC)) { + zend_error(E_ERROR, "Cannot set non exception as previous exception"); + return; + } + if (!exception) { + EG(exception) = add_previous; + return; + } + while (exception && exception != add_previous && Z_OBJ_HANDLE_P(exception) != Z_OBJ_HANDLE_P(add_previous)) { + previous = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 1 TSRMLS_CC); + if (Z_TYPE_P(previous) == IS_NULL) { + zend_update_property(default_exception_ce, exception, "previous", sizeof("previous")-1, add_previous TSRMLS_CC); + return; + } + exception = previous; + } +} + void zend_throw_exception_internal(zval *exception TSRMLS_DC) /* {{{ */ { if (exception != NULL) { - if (EG(exception)) { - zend_update_property(default_exception_ce, exception, "previous", sizeof("previous")-1, EG(exception) TSRMLS_CC); - } + zval *previous = EG(exception); EG(exception) = exception; + zend_exception_set_previous(previous TSRMLS_CC); } if (!EG(current_execute_data)) { zend_error(E_ERROR, "Exception thrown without a stack frame"); @@ -129,8 +153,8 @@ ZEND_METHOD(exception, __construct) zval *object, *previous = NULL; int argc = ZEND_NUM_ARGS(), message_len; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "|slO", &message, &message_len, &code, &previous, default_exception_ce) == FAILURE) { - zend_error(E_ERROR, "Wrong parameters for Exception([string $exception [, long $code ]])"); + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "|slO!", &message, &message_len, &code, &previous, default_exception_ce) == FAILURE) { + zend_error(E_ERROR, "Wrong parameters for Exception([string $exception [, long $code [, Exception $previous = NULL]]])"); } object = getThis(); @@ -158,8 +182,8 @@ ZEND_METHOD(error_exception, __construct) zval *object, *previous = NULL; int argc = ZEND_NUM_ARGS(), message_len, filename_len; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "|sllslO", &message, &message_len, &code, &severity, &filename, &filename_len, &lineno, &previous, default_exception_ce) == FAILURE) { - zend_error(E_ERROR, "Wrong parameters for ErrorException([string $exception [, long $code, [ long $severity, [ string $filename, [ long $lineno ]]]]])"); + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "|sllslO!", &message, &message_len, &code, &severity, &filename, &filename_len, &lineno, &previous, default_exception_ce) == FAILURE) { + zend_error(E_ERROR, "Wrong parameters for ErrorException([string $exception [, long $code, [ long $severity, [ string $filename, [ long $lineno [, Exception $previous = NULL]]]]]])"); } object = getThis(); |