Re: [PRE-RFC] Deprecate returning from a finally block
| From: | Seifeddine Gmati | Date: | Sat, 20 Jun 2026 08:22:17 +0000 |
| Subject: | Re: [PRE-RFC] Deprecate returning from a finally block | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-131415@lists.php.net to get a copy of this message | ||
On Thu, 18 Jun 2026 at 22:58, Osama Aldemeery <aldemeery@gmail.com> wrote:
>
> Hi all,
>
> I'd like to gauge interest in deprecating
return inside a
> finally block, before I request karma to propose it as a full RFC.
>
> A return inside a finally
> silently discards whatever the
> try/catch was doing...a pending
> exception or return value just disappears, with no error or notice.
>
> As far as I know, it's the only abrupt exit from a finally
> PHP leaves silent...
> break/continueÊ
> 2ÿ•$Š SkÏ.½/goto out of one are already compile errors, and a
> throw auto-chains the discarded exception as
> $previous. Only return destroys the
> in-flight state and says nothing.
>
> Looking into the history of finally I found that the author of
> the original RFC said he added it only because Java allowed it, even though he thought it made
> "no sense" https://externals.io/message/61670#61678
> But Java itself warns about it (javac -Xlint:finally).
>
> I also found that it was the source of a few bugs:
>
> https://bugs.php.net/bug.php?id=70228
> https://bugs.php.net/bug.php?id=72213
> https://github.com/php/php-src/issues/11028
>
> To see what a change would actually cost, I implemented the deprecation and ran it over the top
> ~5000 Composer packages. And I found that it's rare....there were only 12 occurrences across 9
> packages out of 4992. Of those, 3 look like genuine latent bugs the deprecation caught, and the rest
> look deliberate.
>
> Here's the list of the occurrences:
>
> ibexa/admin-ui (swallows the exceptions its own docblock declares)
> shopware/core (eats thumbnail failures and still reports success)
> amphp/http-server (drops exceptions when the stream is already gone)
> dvdoug/PHPCoord (deliberate...finally is the method's return)
> dvdoug/PHPCoord (again)
> dvdoug/PHPCoord (again)
> dvdoug/PHPCoord (again)
> spatie/ray (delibrate...any failure just returns false)
> cakephp/cakephp (catch consumed the exception...finally just returns array)
> hyperf/http-server (catch consumed the exception...finally emits response)
> silverstripe/framework (catch consumed the mysqli error)
> symfony/flex (try can't actually throw)
>
> My take here is that the language already handles the analogous cases (äeŸŠ(+õkO
> ’À(continue/break/goto/...etc)
> natively, so leaving return looks like an inconsistency.
>
> I lean toward deprecating it now with an eye to an error in a future major (following the steps
> of Tim's deprecate-return-from-constructor RFC)...though I guess a plain warning would be fine
> too. The main thing is that it seems worth doing something about.
>
> Is there appetite for this?
>
> Thanks,
> Osama
Hi Osama,
I think for the sake of consistency ( and sanity ), this makes sense.
A deprecation phase in 8.x seems appropriate.
Cheers,
Seifeddine.