Re: [RFC] Exceptions in the engine
| From: | Nikita Popov | Date: | Sat, 26 Oct 2013 21:40:44 +0000 |
| Subject: | Re: [RFC] Exceptions in the engine | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-69885@lists.php.net to get a copy of this message | ||
On Thu, Oct 24, 2013 at 8:01 PM, Adam Harvey <aharvey@php.net> wrote:
> On 24 October 2013 10:41, Nikita Popov <nikita.ppv@gmail.com> wrote:
> > I'd like to propose an RFC, which allows the use of exceptions within the
> > engine and also allows changing existing fatal errors to exceptions:
> >
> > https://wiki.php.net/rfc/engine_exceptions
> >
> > This topic has been cropping up in the discussions for several of the
> > recent RFCs and I think the time has come to consider moving away from
> > fatal errors.
>
> I love the idea — unified error and exception handling would be a huge
> win both for simplifying code bases and teaching new developers — but
> I don't see any possible way we could do this in a 5.x release. The BC
> issues are just too great, and too many people rely heavily on the
> set_error_handler() behaviour that we have today.
>
Reading through the mails in this thread a lot of people seem to have
concerns about backwards compatibility. I can see where this comes from,
"switch to using exceptions" certainly sounds like a seriously big BC break
- but I don't think it actually is.
Let's start by considering only E_ERROR (and leave recoverable fatals for
later):
First of all we should establish that fatal errors do not occur during
normal program execution. If you take your PHP 5.5 program and run it on
PHP 5.6 (with E_ERROR converted to exceptions) you will see *absolutely no
difference*. If you do, that means your code was previously throwing a
fatal error already, i.e. it didn't actually work in the first place. Let
me say this again, because I think it's important: If your code was working
previously, it will continue working the same way after converting fatals
to exceptions.
But what happens when the program has a bug and does throw a fatal error?
In this case the program already doesn't work, so what changes isn't
particularly critical, but we should still consider it. There are basically
two things that might happen:
1. Most likely everything will work just as you expect, the error will only
be presented differently. Either because the exception is not handled and
the message changes because of that (with stack trace) or an
exception-handler or top-level catch-block handles it rather than the
shutdown function and presents it in some different way. In either case
this shouldn't matter - I certainly do hope that changing the look of an
error is not considered a compatibility break...
2. A misplaced catch-and-ignore block catches the fatal error and dismisses
it. This is of course unfortunate, but it's really not more than that. It's
an inconvenience, yes, but it does not actually break anything. Some people
have mentioned something about code-paths becoming reachable that were
previous not, but I don't see how that applies. If you used a try/catch
block, then you already expect that the code-path in the catch or the code
after it may be taken. At this point I'd also like to point out that if
code contains a catch-all block, it likely is also supposed to catch-all,
so hiding the error is likely not even wrong. PHP never did Java's mistake
of introducing checked exceptions, so PHP does not have a widespread
pattern of "wrap everything with catch(Exception $e) to silence the
compiler".
So, that much on fatal errors. What about E_RECOVERABLE_ERROR?
Here there may actually be BC issues. As already mentioned, recoverable
fatals can currently be ignored with a custom error handler and exceptions
make that impossible. So it might be that someone wrote an application that
throws recoverable errors during "normal" program execution. I don't think
that this is particularly realistic and as such I don't think this is
really problematic, but others might see this differently. If that is the
case it might become necessary to keep recoverable fatal errors as is.
In conclusion, I don't see any non-negligible BC issues for the fatal-error
change and only minor BC issues for the recoverable-fatal change (and even
that can be dropped). As such I don't think pushing this off to PHP 6 is
justified. I'd also like to point out that this RFC is a blocker for some
of my other proposals. In particular, I don't think that I can in good
conscience move the named arguments and argument unpacking RFCs forward
without the ability to use exceptions. I would really hate to move named
args off to PHP 6.
Thanks,
Nikita