Stefano php, milano

How to handle exceptions from __toString

This is a modified excerpt of an answer of mine on StackOverflow.

I came up with a (perhaps) better way to handle exceptions inside __toString():

public function __toString()
{
    try {
        // ... do some stuff
        // and try to return a string
        $string = $this->doSomeStuff();
        if (!is_string($string)) {
            // we must throw an exception manually here because if $value
            // is not a string, PHP will trigger an error right after the
            // return statement, thus escaping our try/catch.
            throw new \LogicException(__CLASS__ . "__toString() must return a string");
        }

        return $string;
    } catch (\Exception $exception) {
        $previousHandler = set_exception_handler(function (){
        });
        restore_error_handler();
        call_user_func($previousHandler, $exception);
        die;
    }
}

This assumes there is an exception handler defined, which is the case for most frameworks. As with the trigger_error method, doing this will defy the purpose of try..catch, but still it is much better than dumping output with echo. Also, many framework transform errors into exceptions, so trigger_error won't work anyway.

As an added bonus, you'll get a full stack-trace as with normal exceptions and the normal dev-production behaviour of your framework of choice.

Works very well in Laravel, and I'm pretty sure it'll work in pretty much all the modern PHP frameworks out there.

Screenshot relevant:
note: in this example, output() is called by a __toString() method.

__toString() exception caught by Laravel exception handler

Tags: php