On 08/01/2015 09:44 AM, Markus Malkusch wrote:
Christoph Becker:
Markus Malkusch wrote:

I'd like to revise that. I'd just learned that finally does indeed fit
here, as it would automatically glue exceptions:

[..]

Note that there's an open bug report (<https://bugs.php.net/68270>)
regarding this issue.

Thank you for pointing to that bug. So I understand the authors of that
bug are surprised that finally does magically attach exceptions. I did
actually also not expect that, as it is not documented nor do I have
that experience from other languages (did only check with Java).

So I can assume that magic finally glue behaviour is not considered
stable, which then again gives Throwable::addSupressed() IMO a
justification.

Markus Malkusch


So what should be the desired behavior, in regard to bug #68270? One possible behavior would be to, if an exception is thrown inside a finally block, to attach the uncaught exception from the try block via the addSupressed() method. The last exception is thrown, and the exception in the try block is still not lost. Such an alternative could be bundled with the RFC.

The alternative s to just drop the exception, never to be seen again. This is the behavior in both Java and C#. Python has a different approach. Python has two properties that contain previous exceptions: __context__, which holds implicitly chained exceptions, and __cause__, which holds explicitly chained exceptions. This system makes a ton of sense, and I think PHP exceptions should distinguish between the two as well.

(Relevant PEP: <https://www.python.org/dev/peps/pep-3134/>)

Currently, in the try/finally situation described, $previous is used to hold the missing exception. $previous should only hold explicitly passed exceptions, as described in the docs. addSupressed() could be defined as for implicit chained exceptions. The method could be paired with a Throwable::getSupressed() to retrieve the implicitly added exception.

So in a case like this:

try {
    try {
        throw new Exception("Exception 1");
    } finally {
        throw new Exception("Exception 2");
    }
} catch (Throwable $e) {
    var_dump($e->getSupressed());
}

we would have $e be exception 2, and $e->getSupressed() return exception 1.

The more I think about it, the better the idea sounds. Good thought, Markus!

--
Stephen Coakley

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to