Nikita, Philip, see below:
> -----Original Message-----
> From: Philip Sturgeon [mailto:pjsturgeon@gmail.com]
> Sent: Monday, December 09, 2013 8:10 PM
> To: Nikita Popov
> Cc: Zeev Suraski; PHP internals
> Subject: Re: [PHP-DEV] [VOTE] Allowing use of exceptions in the engine
>
> On Mon, Dec 9, 2013 at 11:41 AM, Nikita Popov <nikita.ppv@gmail.com>
> wrote:
> >
> > You can't convert fatal errors to exceptions using an error handler.
> > That's why I'm targeting fatal errors here and not all errors in
> > general. While I'm not a big fan of PHP's error system in general,
> > it's easy enough to turn warnings or notices into exceptions via error
> > handlers. But for fatal errors that's just not possible.
That's correct, but you seem to be ignoring the reason for that. It's not
an arbitrary decision, but rather, the semantics of what fatal errors are.
They're fatal, not recoverable (with the reason being that the
engine/extension/whatever may be in an unstable state), and therefore it
should not be possible to use *any* mechanism to recover from them, be
them error handlers or exceptions.
> > To achieve what I want it would be enough to turn fatal errors into
> > recoverable fatal errors, that would already allow the error handler
> > approach. But that's a lot harder to do (and imho less usable) than
> > directly using exceptions. Keeping the engine stable after an
> > exceptions is relatively simple, the same can't be said about
recoverable
> fatals.
In both cases, the complexity isn't in the code that would trigger the
error/exception. The complexity is that you now put the burden of keeping
all the data structures of the engine/extension in a 100% working state,
while the current semantics is that code execution will never resume.
While you pointed out in the RFC a specific example of a place where an
exception would be a bit easier to implement than an error, it's a very
specialized example - errors that happen on the void between two function
scopes - and doesn't hold true for most errors. I don't think it makes
sense to say it's significantly easier to turn fatal errors into
exceptions than turning fatal errors into recoverable errors.
> > Regarding the "forcing OO concepts": As Philip pointed out, unless you
> > already make use of try/catch a fatal error and an uncaught exception
> > are about the same to the end user - actually, an uncaught exception
> > is just a special fatal error.
First off, there should be no concept of 'recoverable fatal error'. If
it's fatal, it cannot be recoverable and vice versa. The real term should
just be 'recoverable error'. That small detail may be in the root of our
misunderstanding. All the negative side effects listed in the RFC for
fatal errors are in there *by design*, since we cannot guarantee that if
we run the destructors/finally blocks or otherwise allow graceful
handling, this will not result in a segfault. That's exactly the whole
idea beyond a fatal (by definition non-recoverable) error.
Secondly, the patch radically changes execution behavior in case of
recoverable errors for people using error handlers and arguably in a very
bad way, effectively forcing them to start using exceptions if they want
to truly recover from the error. Otherwise, by the time the exception
turns into an error, there's nothing you can recover (you've already
bubbled up all the way to the global scope). That will break apps relying
on the current behavior.
Last, in the RFC it mentions that 'recoverable errors are hard to catch'.
That you're forced to use an error_handler. How are they any different
from any other error/warning type? While you (and many others) have bias
for using exception handling, others prefer using error_handlers
especially when writing procedural code. Changing errors to exceptions
using an error handler is trivial (and we can also implement Seva's
suggestion of having an INI directive for that, although I think using a
serializable error handler makes more sense). The reverse, however, is
not even possible. So I very much stand by what I said, that if we accept
this RFC, we're forcing OO concepts (or the try/catch concept) on all
users which is something that we intentionally wanted to avoid. Users who
could use centralized error handlers will no longer be able to do so and
handle recoverable errors.
> > concerns - if this discussion weren't about fatal errors. E.g.
> > changing a warning to an exception would cause lots of issues. The @
> > operator would stop working and people would be forced to use
> > try/catch. But for fatals @ never worked in the first place. You can't
> > handle them right now. Changing them to exceptions adds the ability to
> > handle them via try/catch, but of course you don't need to do them.
> > You can let them bubble (and in most cases that's what you should do)
> > and let them effectively act the same way as a fatal error currently
> > does, just with a bit of a different message ;)
Again, I think that in the majority of the cases, if you can safely turn
an E_ERROR onto an exception, you can just as easily turn it into an
E_RECOVERABLE_ERROR. It makes no sense, IMHO, to tie this effort together
with changing the semantics of how the engine reports problems, and more
so - change it in a way that inconsistent across different error types AND
breaks backwards compatibility in a pretty big way (for recoverable
errors).
> 1. Users who previously did not care about exceptions will continue to
not
> care about exceptions, and do not have to do anything any differently.
Given that most (all minus one) of the people in favor of this idea voted
'yes' and not for the second 'yes w/o E_RECOVERABLE_ERROR', that's not
exactly accurate. That means that recovery code that worked fine with
E_RECOVERABLE_ERROR will now break, and it won't be possible to fix it w/o
learning exceptions and adding try/catch blocks all over the application.
> 2. Users who want to handle fatal errors somehow (because you currently
> cannot) can use this to catch them.
I think we're way too optimistic about the ability to recover from places
which are marked by E_ERROR today, and that turning them to exceptions is
hardly the magical solution that just makes all the
inconsistency/stability issues go poof.
> Nobody needs to work with exceptions if they dont want to, that fatal
error
> just shows up as a uncaught backtrace and fatals errors just like it
used to.
>
> Seems like a win win.
Seems more like a lose/risk situation to me (lose BC for recoverable
errors, take risk with inconsistent data structures for fatal errors).
Zeev