Exception::fillException() proposal

php.internals

Antony Dovgal

20 years ago
Hello all. I'd like to propose addition of a new method of standard Exception class. This method is somewhat identical to Java's fillInStackTrace() [0], but fills not only the "trace", but also "line" and "file" properties. See #33407 [1], this report explains how this method can be used. Short example: Exception::fillException() (the name is still under question) returns new exception object that can be used this way: <?php try { throw new Exception("message", 1); } catch(Exception $e) { throw $e->fillException(); } ?> In the code above "line", "file" and "trace" properties will point at the file/line where fillException() is called, not the file/line where $e was constructed. All the other properties of $e are copied, so they remain untouched. See diff against HEAD in attachment. [0] http://java.sun.com/j2se/1.3/docs/api/java/lang/Throwable.html#fillInStackTrace() [1] http://bugs.php.net/bug.php?id=33407
-- Wbr, Antony Dovgal

Marcus Börger

20 years ago
Hello Antony, in general modifying exception data is vey dangerous because first it leads to confusion on the usage part and second it might lead to sever problems in the engine facilities that deal with them. That this in a few cases worked does not mean it works in all cases it mybe be used. On another reason we should have a look why Java comes with such a thing. In Java you don't have automatic stack frame cleaning as you have in c++ for example. Thus when a function might throw an exception which is the usual case in Java you must catch the exception locally cleanup you local data manually and rethrow the exception. Now you must understand that Java took a very differetn design approach than either C++ but even also very different from PHP. Since C++ is out of interest besides above mentioned fact we just need to look at Java and PHP. Java has no builtin error notification facilities like PHP has. Also they don't have pass by reference. Therefore the only ways to notify of function failures are returning a functionality info (boolean or error code or even objects), using exceptions, modifying the objects state. Of these the APIs chose to use exceptions so everyone else followed this scheme. Now in PHP we chose to use exceptions only where no other solution is possible (ctor failure) and have exceptions else for user scenarios where it can be very helpfull. While in Java exceptions have become normalities and a lot of stuff has been established to make them even more normal the infrastucture has always been designed to treat exceptions as a very native, common and deeply integrated thing. This is pretty different in PHP where exceptions are a tiny addon. To prevent us from adding all the stuff Java invented to deal more gracefull with exceptions starting with the ability to handle more than one exception at a time i would like to stay with the KISS approach and have them as easy as possible. best regards marcus Tuesday, January 10, 2006, 2:42:56 PM, you wrote:
> Index: Zend/zend_exceptions.c > =================================================================== > RCS file: /repository/ZendEngine2/zend_exceptions.c,v > retrieving revision 1.94 > diff -u -p -d -r1.94 zend_exceptions.c > --- Zend/zend_exceptions.c 4 Jan 2006 23:52:06 -0000 1.94 > +++ Zend/zend_exceptions.c 10 Jan 2006 13:24:57 -0000 > @@ -294,6 +294,37 @@ ZEND_METHOD(error_exception, getSeverity > } > /* }}} */ > > +/* {{{ proto int ErrorException::fillException() > + Fill in exception properties */ > +ZEND_METHOD(exception, fillException) > +{ > + zval *exception = getThis(); > + zval *trace, tmp; > + zend_object *object; > + > + DEFAULT_0_PARAMS; > + > + INIT_PZVAL(return_value); > + Z_TYPE_P(return_value) = IS_OBJECT; > + Z_OBJVAL_P(return_value) = zend_objects_new(&object, Z_OBJCE_P(exception) TSRMLS_CC); > + Z_OBJ_HT_P(return_value) = Z_OBJ_HT_P(exception); > + > + ALLOC_HASHTABLE(object->properties); > + zend_u_hash_init(object->properties, 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode)); > + zend_hash_copy(object->properties, Z_OBJPROP_P(exception), > (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); > + > + ALLOC_ZVAL(trace); > + trace->is_ref = 0; > + trace->refcount = 0; > + > + zend_fetch_debug_backtrace(trace, 0, 0 TSRMLS_CC); > + > + zend_update_property(Z_OBJCE_P(exception), return_value, "trace", sizeof("trace")-1, trace TSRMLS_CC); > + zend_update_property_rt_string(Z_OBJCE_P(exception), > return_value, "file", sizeof("file")-1, > zend_get_executed_filename(TSRMLS_C) TSRMLS_CC); > + zend_update_property_long(Z_OBJCE_P(exception), return_value, > "line", sizeof("line")-1, zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC); > +} > +/* }}} */ > + > /* {{{ ZEND_METHOD(exception, gettraceasstring) */ > #define TRACE_APPEND_CHR(chr) \ > *str = (char*)erealloc(*str, *len + 1 + 1); > @@ -604,6 +635,7 @@ static zend_function_entry default_excep > ZEND_ME(exception, getTrace, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) > ZEND_ME(exception, getTraceAsString, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) > ZEND_ME(exception, __toString, NULL, 0) > + ZEND_ME(exception, fillException, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) > {NULL, NULL, NULL} > }; >
Best regards, Marcus

Antony Dovgal

20 years ago
On 11.01.2006 00:41, Marcus Boerger wrote:
> Hello Antony, > > in general modifying exception data is vey dangerous because first it > leads to confusion on the usage part and second it might lead to sever > problems in the engine facilities that deal with them. That this in a > few cases worked does not mean it works in all cases it mybe be used.
Actually, the code doesn't modify any data there, but copies it instead. That is: create new object, copy data from the old one, update few properties.
> To prevent us from adding all the stuff Java invented to deal more > gracefull with exceptions starting with the ability to handle more than > one exception at a time i would like to stay with the KISS approach and > have them as easy as possible.
I realize that it's relatively easy to implement this in PHP, but in the same time I don't see in what way adding this function violates the KISS approach. Could you plz elaborate?
-- Wbr, Antony Dovgal

Marcus Börger

20 years ago
Hello Antony, Tuesday, January 10, 2006, 10:56:21 PM, you wrote:
> On 11.01.2006 00:41, Marcus Boerger wrote: >> Hello Antony, >> >> in general modifying exception data is vey dangerous because first it >> leads to confusion on the usage part and second it might lead to sever >> problems in the engine facilities that deal with them. That this in a >> few cases worked does not mean it works in all cases it mybe be used.
> Actually, the code doesn't modify any data there, but copies it instead. > That is: create new object, copy data from the old one, update few properties.
And you are sure there is no way this can be executed during shutdown sequence?
>> To prevent us from adding all the stuff Java invented to deal more >> gracefull with exceptions starting with the ability to handle more than >> one exception at a time i would like to stay with the KISS approach and >> have them as easy as possible.
> I realize that it's relatively easy to implement this in PHP, but in the same time I don't > see in what way adding this function violates the KISS approach. > Could you plz elaborate?
You are turining Exceptions into Normalities. Best regards, Marcus

Antony Dovgal

20 years ago
On 11.01.2006 01:00, Marcus Boerger wrote:
> Hello Antony, > > Tuesday, January 10, 2006, 10:56:21 PM, you wrote: > >> On 11.01.2006 00:41, Marcus Boerger wrote: >>> Hello Antony, >>> >>> in general modifying exception data is vey dangerous because first it >>> leads to confusion on the usage part and second it might lead to sever >>> problems in the engine facilities that deal with them. That this in a >>> few cases worked does not mean it works in all cases it mybe be used. > >> Actually, the code doesn't modify any data there, but copies it instead. >> That is: create new object, copy data from the old one, update few properties. > > And you are sure there is no way this can be executed during shutdown > sequence?
Except for __destruct() I don't see any other ways for it to be executed during shutdown. And we know that exceptions work fine in __destruct().
>>> To prevent us from adding all the stuff Java invented to deal more >>> gracefull with exceptions starting with the ability to handle more than >>> one exception at a time i would like to stay with the KISS approach and >>> have them as easy as possible. > >> I realize that it's relatively easy to implement this in PHP, but in the same time I don't >> see in what way adding this function violates the KISS approach. >> Could you plz elaborate? > > > You are turining Exceptions into Normalities.
Huh?
-- Wbr, Antony Dovgal