Re: [PRE-RFC] Deprecate returning from a finally block
| From: | Larry Garfield | Date: | Fri, 19 Jun 2026 16:30:22 +0000 |
| Subject: | Re: [PRE-RFC] Deprecate returning from a finally block | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-131411@lists.php.net to get a copy of this message | ||
On Thu, Jun 18, 2026, at 4:49 PM, Osama Aldemeery 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/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
>
> <https://github.com/php/php-src/compare/master...aldemeery:php-src:deprecate-return-in-finally>
>
> 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:
> 1. ibexa/admin-ui (swallows the exceptions its own docblock declares)
>
> <https://github.com/ibexa/admin-ui/blob/2322d54/src/bundle/Controller/ContentTypeController.php#L834>
> 2. shopware/core (eats thumbnail failures and still reports success)
>
> <https://github.com/shopware/core/blob/e8079a0/Content/Media/Thumbnail/ThumbnailService.php#L294>
> 3. amphp/http-server (drops exceptions when the stream is already
> gone)
>
> <https://github.com/amphp/http-server/blob/b306134/src/Driver/Http2Driver.php#L1322>
> 4. dvdoug/PHPCoord (deliberate...finally is the method's return)
>
> <https://github.com/dvdoug/PHPCoord/blob/ced02c4/src/Point/CompoundPoint.php#L131>
> 5. dvdoug/PHPCoord (again)
>
> <https://github.com/dvdoug/PHPCoord/blob/ced02c4/src/Point/GeocentricPoint.php#L148>
> 6. dvdoug/PHPCoord (again)
>
> <https://github.com/dvdoug/PHPCoord/blob/ced02c4/src/Point/GeographicPoint.php#L221>
> 7. dvdoug/PHPCoord (again)
>
> <https://github.com/dvdoug/PHPCoord/blob/ced02c4ad44aa4a558f69d53af4834a9d50ab2aa/src/Point/ProjectedPoint.php#L242-L247>
> 8. spatie/ray (delibrate...any failure just returns false)
>
> <https://github.com/spatie/ray/blob/2da2079/src/Client.php#L71>
> 9. cakephp/cakephp (catch consumed the exception...finally just
> returns array)
>
> <https://github.com/cakephp/cakephp/blob/eef91f28de119bee5536905244d2096f752f2920/src/Database/Query.php#L1748-L1755>
> 10. hyperf/http-server (catch consumed the exception...finally emits
> response)
> <Ž0vTgˆÃý®"(M
> nGhttps://github.com/hyperf/http-server/blob/80c52d4/src/Server.php#L140>
> 11. silverstripe/framework (catch consumed the mysqli error)
>
> <https://github.com/silverstripe/silverstripe-framework/blob/9c59c42/src/ORM/Connect/MySQLiConnector.php#L213>
> 12. symfony/flex (try can't actually throw)
>
> <https://github.com/symfony/flex/blob/4a6d98e/src/PackageResolver.php#L88>
> My take here is that the language already handles the analogous cases
>
> (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
>
> <https://wiki.php.net/rfc/deprecate-return-value-from-construct>)...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
I think this makes sense, but it would definitely need to go through a Deprecation phase. I
don't think it needs its own RFC; It can probably go into the omnibus deprecations RFC for this
version. (Which should get going very soon.)
--Larry Garfield