Stephen Coakley:
> Interesting thought, but how is this different than including a previous
> throwable and throwing a new, more descriptive exception?

Thank you for asking. If you would have again a look at the code
fragment from the previous mail you will notice that there are two
immutable exceptions: $e1 and $e2. But only one exception may leave the
context. There is no possibility to attach $e2 to $e1, so some
information will get lost.

Also the scenario could be extended to n further exceptions, as n
further resources might need some clean up operations.

> What you're describing doesn't seem like a common use case.

I'd argue it is. Just imagine there are remaining resources which you
really want to release in any case (e.g. releasing a lock). In the case
of an exception (from the code before the releasing), this exception
should leave the method plus the resources should be closed. Now what
happens if closing those resources cause further exceptions? Only one
exception may leave the method.

Also other languages (e.g. Python and Java) decided that this use case
is common enough.

I'd like to illustrate it with a further more verbose example:

public function withdraw($amount)
{
    $this->lock();
    try {
        // Let's assume anything here can throw an exception.

        $balance = $this->getBalance();
        $balance -= $amount;
        $this->saveBalance($balance);
        $this->unlock(); // throws LockException

    } catch (LockException $e) {
        // Releasing failed, so nothing else to do and that's the only
        // exception, so we're good here.
        throw $e;

    } catch (\Exception $e1) {
        // unlock() was not called yet.
        assert ($this->isLocked());
        try {
            $this->unlock();
            // The resource was released and we can throw $e1.
            throw $e1;

        } catch (LockException $e2) {
            // Now I can only throw $e1 or $e2, that's why I add $e2.
            $e1->addSuppressed($e2);
            throw $e1;
        }
    }
}

> the above code might fit better with a finally block when closing resources:
> 
> try {
>     // Do something with $resource here...
> } finally {
>      $resource->close();
> }

Finally doesn't address this use case. With finally I would just
exchange any origin exception with a possible exception from the close()
operation.

But I agree that try {} catch {try {catch {}} is quiet a huge boiler
plate. That's why Java introduced together with
Throwable::addSupressed() the try-with-resource statement. I would also
love to see try-with-resource here, but for the beginning I'd like to
focus on Throwable::addSupressed().

So do you still see no use case?

Markus Malkusch

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

Reply via email to