- fix nested exception suppression and order
[m6w6/ext-http] / http_api.c
index acff118b1f9edd40b9d678f549a327a85e22c306..fef29305672e645a80fa4503f9ccae59c1a4cdae 100644 (file)
@@ -116,33 +116,43 @@ void _http_error_ex(long type TSRMLS_DC, long code, const char *format, ...)
 /* {{{ zval *http_exception_wrap(zval *, zval *, zend_class_entry *) */
 zval *_http_exception_wrap(zval *old_exception, zval *new_exception, zend_class_entry *ce TSRMLS_DC)
 {
-       zval **args, **trace_0, *old_trace_0, *trace = NULL;
-       
        /* create wrapping exception if requested */
        if (!new_exception) {
+               zval **args, **trace_0, *old_trace_0, *trace = NULL;
+               
                MAKE_STD_ZVAL(new_exception);
                object_init_ex(new_exception, ce);
                zend_update_property_string(ce, new_exception, "message", lenof("message"), "Exception caused by inner exception(s)" TSRMLS_CC);
-       }
+               zend_update_property(Z_OBJCE_P(new_exception), new_exception, "innerException", lenof("innerException"), old_exception TSRMLS_CC);
        
-       /* copy bt arguments */
-       if ((trace = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), old_exception, "trace", lenof("trace"), 0 TSRMLS_CC))) {
-               if (Z_TYPE_P(trace) == IS_ARRAY && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(trace), 0, (void *) &trace_0)) {
-                       old_trace_0 = *trace_0;
-                       if (Z_TYPE_PP(trace_0) == IS_ARRAY && SUCCESS == zend_hash_find(Z_ARRVAL_PP(trace_0), "args", sizeof("args"), (void *) &args)) {
-                               if ((trace = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), new_exception, "trace", lenof("trace"), 0 TSRMLS_CC))) {
-                                       if (Z_TYPE_P(trace) == IS_ARRAY && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(trace), 0, (void *) &trace_0)) {
-                                               ZVAL_ADDREF(*args);
-                                               add_assoc_zval(*trace_0, "args", *args);
+               /* copy bt arguments */
+               if ((trace = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), old_exception, "trace", lenof("trace"), 0 TSRMLS_CC))) {
+                       if (Z_TYPE_P(trace) == IS_ARRAY && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(trace), 0, (void *) &trace_0)) {
+                               old_trace_0 = *trace_0;
+                               if (Z_TYPE_PP(trace_0) == IS_ARRAY && SUCCESS == zend_hash_find(Z_ARRVAL_PP(trace_0), "args", sizeof("args"), (void *) &args)) {
+                                       if ((trace = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), new_exception, "trace", lenof("trace"), 0 TSRMLS_CC))) {
+                                               if (Z_TYPE_P(trace) == IS_ARRAY && SUCCESS == zend_hash_index_find(Z_ARRVAL_P(trace), 0, (void *) &trace_0)) {
+                                                       ZVAL_ADDREF(*args);
+                                                       add_assoc_zval(*trace_0, "args", *args);
+                                               }
                                        }
                                }
                        }
                }
+               
+               zval_ptr_dtor(&old_exception);
+               return new_exception;
+       } else {
+               zval *sub_exception = old_exception, *top_exception = old_exception;
+               
+               while ((sub_exception = zend_read_property(ZEND_EXCEPTION_GET_DEFAULT(), sub_exception, "innerException", lenof("innerException"), 0 TSRMLS_CC)) && Z_TYPE_P(sub_exception) == IS_OBJECT) {
+                       top_exception = sub_exception;
+               }
+               zend_update_property(Z_OBJCE_P(top_exception), top_exception, "innerException", lenof("innerException"), new_exception TSRMLS_CC);
+               
+               zval_ptr_dtor(&new_exception);
+               return old_exception;
        }
-       
-       zend_update_property(Z_OBJCE_P(new_exception), new_exception, "innerException", lenof("innerException"), old_exception TSRMLS_CC);
-       zval_ptr_dtor(&old_exception);
-       return new_exception;
 }
 /* }}} */
 #endif /* ZEND_ENGINE_2 */