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
>

Reply via email to