I've heard the technical explanation before, and while it probably doesn't make sense to go through all that effort to fix this... well... take this example:
class Foo { public function __toString() { try { return $this->bar(); } catch (Exception $e) { trigger_error(E_USER_ERROR, $e->__toString()); } } protected function bar() { throw new RuntimeException('ouch'); } } $test = new Foo(); echo $test; This is OK in theory, but just rather odd, and won't work with many frameworks and error-handlers, if errors are caught and thrown as the built-in ErrorException - the natural expectation would be that this should be enough: public function __toString() { return $this->bar(); } What if that basically did the same thing? An implicit try/catch inside __toString() as above, but instead of passing the error to trigger_error() and triggering the error-handler, pass it to the built-in exception-handler, or whatever was configured with set_exception_handler() That way, we would at least get a meaningful error message, even if it's still not possible for exceptions to bubble up through implicit calls made to __toString() internally. Wouldn't that at least suck less? :-) On Thu, May 9, 2013 at 6:50 PM, Etienne Kneuss <col...@php.net> wrote: > > > > On Fri, May 10, 2013 at 12:00 AM, Rasmus Schultz > <m...@rasmus-schultz.com>wrote: > >> I just ran into this issue again: >> >> >> http://stackoverflow.com/questions/2429642/why-its-impossible-to-throw-exception-from-tostring >> >> Instead of throwing some nonsense "you're not allowed to throw from here" >> error-message, how about actually unwinding the stack and passing the >> exception to the global exception-handler? >> >> I understand there's a technical limitation making it difficult/impossible >> to handle exceptions during __toString() - and it looks like you can still >> try {...} catch (Exception $e) in __toString() just fine, but then what? >> You have the exception, but you have no way to pass it to the standard >> global exception-handler. >> >> If the script has to terminate either way, why not terminate the same way >> an unhandled exception would normally cause the script to terminate? >> >> E.g. output the actual error-message, or pass it to whatever was >> registered >> with register_exception_handler() so it can be output or handled in the >> usual way? >> > > > The reason is that toString can be triggered from a lot of internal > places. > If an exception is thrown and caught within toString, it's not a problem. > The problem is if the exception escapes toString, because it thus means > that the code invoking toString must be interrupted. > > We in fact have no guarantee that all those internal places will work > consistently/correctly in the presence of an exception, and if the engine > will remain in a state that allows executing code afterward. > Not executing code means we need to bypass error handlers as well. > > Handling an exception from internal code is a "manual" procedure, and code > written that relies on conversions to strings may not have been written > with support for exceptions in mind. > > I guess the alternative approach is to allow exceptions, review the code > (i.e. a lot of work), and eventually fix reports as they come in. > > Best, > > -- > Etienne Kneuss >