FAQ
Hi internals!

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.

Thoughts?

Thanks,
Nikita

Search Discussions

  • Johannes Schlüter at Oct 24, 2013 at 5:57 pm

    On Thu, 2013-10-24 at 19:41 +0200, Nikita Popov wrote:
    Hi internals!

    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:
    If there is a way to recover from a fatal error it shouldn't be E_ERROR
    but E_RECOVERABLE. Catching E_RECOVERABLE is a pita. this should be
    replaced by exceptions imo.

    E_FATAL should stay for things where it is too much trouble to recover
    as the engine is in undefined state.

    johannes
  • Adam Harvey at Oct 24, 2013 at 6:01 pm

    On 24 October 2013 10:41, Nikita Popov 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.

    Thoughts?
    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.

    A couple of specific points that jumped at out me on my first skim:

    1. I know Python has BaseException, but it feels a little like the
    exception version of functions with the name "real" in them. :) If
    this was $next_major material, then we could probably look at keeping
    Exception as the top level and inserting a UserException under it that
    userland exceptions derive from. (Or just not do it at all.)

    2. Again, if this is $next_major material, I wouldn't selectively
    convert errors to exceptions as the "policy changes" section suggests
    — let's do them all and be done with it, and the only things that
    would still be errors are genuinely uncatchable things that already
    can't be handled by set_error_handler().

    There's probably a broader discussion here around whether we should be
    starting to think about a new major release and what that would look
    like, but that's definitely not for this thread!

    Adam
  • Rowan Collins at Oct 24, 2013 at 8:28 pm

    On 24/10/2013 19:01, Adam Harvey wrote:
    On 24 October 2013 10:41, Nikita Popov 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
    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.
    FWIW, as an outsider, I'd tend to agree with this. It might be possible
    to implement this in a backwards compatible way, but there would be a
    lot of details to consider. More importantly, if this isn't a big enough
    change to warrant a major release, what is? The more major features make
    it into 5.x, with BC carefully maintained, the more it feels like 5.x
    will go on living indefinitely, with the implication - according to the
    current release process - that deprecated or broken APIs will "never" be
    removed or fixed.
    I wouldn't selectively convert errors to exceptions as the "policy changes" section suggests
    — let's do them all and be done with it
    This I agree with even more strongly, but I also don't think this should
    be a one-to-one mapping of the existing errors. From what I can see, the
    current patch uses neither sub-classes nor exception codes, just the
    existing message strings. This seems like a massive missed opportunity -
    a big part of exception handling is choosing which exceptions to handle,
    and at the moment, the only way to detect what error was thrown is by
    string matching, including accounting for substituted parts.

    It would also be nice to consider changing the handling of non-fatals as
    well, although I'm not quite sure how they should work. Again, there is
    currently no way to detect the "type" of a warning or notice, only its
    severity; nor is there an easy way to have different handlers for
    different severities. Those severities can also be pretty arbitrary:
    e.g. an undefined constant issues an E_NOTICE, but a class constant is
    E_ERROR, presumably for historical reasons, which would matter less if
    there were additional meta-data to recognise them by.

    The other rather more blue-sky thought I had is that it would be nice to
    scope error-handling "lexically", in the sense of all functions in a
    particular included library being under a different error-handling
    regime from the outer program, reagardless of execution order. There are
    old modules in PEAR which work fine with current versions of PHP, but
    emit lots of E_DEPRECATED or E_NOTICE messages; what I really want to
    say is "yes, our use of that whole module is deprecated, we're not going
    to clean it up, but our own code should be nice and clean".

    Regards,

    --
    Rowan Collins
    [IMSoP]
  • Nikita Popov at Oct 26, 2013 at 9:40 pm

    On Thu, Oct 24, 2013 at 8:01 PM, Adam Harvey wrote:
    On 24 October 2013 10:41, Nikita Popov 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
  • Alexey Zakhlestin at Oct 27, 2013 at 8:04 am

    On 27 окт. 2013 г., at 1:40, Nikita Popov wrote:

    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): +1
    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".
    I think it is a good idea to avoid #2 altogether by introducing BaseException and using separate hierarchy for ex-fatal errors.
    old code will ignore new exceptions and those will fall thru down to generic exception-handler and shutdown-handler

    New code will be able to use `catch (BaseException $e)` but that should be deliberate decision by code-author
    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.
    I think “safe" set of changes (E_ERROR + separate exceptions-hierarchy) should be implemented in 5.6.
    Everything else should be planned for 6.x
  • Rowan Collins at Oct 27, 2013 at 1:47 pm

    On 26/10/2013 22:40, Nikita Popov wrote:
    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.
    As I understand it, the current release process doesn't say anything
    about "big" or "major" BC breaks, but that minor releases should not
    break BC *at all*. There may be justification for relaxing that rule,
    but the justification needs to be made.
    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.
    There's a subtlety here that could be important - a script that causes
    fatal errors *in some situations* could still work in other situations.
    This is not like allowing previously invalid syntax, where an entire
    file would previously have failed to compile, these are fundamentally
    run-time behaviours, even if they *should* never happen.
    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.
    I think the comment you're referring to was mine
    [http://php.markmail.org/message/n3aw4kqhclwvpsvs] so I'll expand on it
    a little.

    Ignoring catch-all blocks, to which BaseException is a trivial
    solution/workaround, part of the stated advantage of this change is that
    finally blocks and destructors will run if a fatal error occurs. That
    means that code is running in an application state which was previously
    impossible (except for in the very limited case of the shutdown handler).

    For instance, if a mis-configured deployment meant that a particular
    class could not be autoloaded, that would previously have halted all
    code as soon as an attempt was made to use it. With an exception model,
    however, finally blocks and destructors, which might themselves rely on
    that class in some subtle way, would attempt to run. Hopefully, this
    wouldn't cause anything other than a pile of further errors - it might
    even transparently increase robustness - but it's not impossible to
    imagine a situation where such an application state would corrupt data
    or expose a security flaw.

    I don't know whether to consider this a "major" or "serious" change in
    behaviour, let alone whether it would generally be "good" or "bad", but
    it is a change in behaviour.
    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".
    Actually, I would have thought checked exceptions would make catch-alls
    *less* likely, because you know for sure which exceptions need to be
    handled. In PHP, you can't rely on lower-level exceptions having been
    handled or wrapped up by libraries, so there's a possibility of e.g. a
    PDO_Exception cropping up in the middle of your business logic. But
    that's really beside the point I think - people can use catch(Exception)
    for whatever they like, and speculation about how many people will be
    affected by a BC break is not the same as understanding what the BC
    break is.
    As such I don't think pushing this off to PHP 6 is justified.
    It feels like there's an assumption here that PHP 6 is a long way away.
    Rather than seeing it as pushing this feature away, it could be seen as
    pulling a major release closer. See e.g. Ferenc's suggestion to create
    separate branches for next-minor and next-major:
    http://php.markmail.org/message/v4gzpnfn7x6xonjs

    The other question is, what's the hurry? If this is introduced
    piecemeal, the result is an even more fragmented error-handling model,
    with a few slightly improved features, some of the time. And then when a
    plan is put together to overhaul error handling in general, the way
    EngineExceptions work will have to be worked into the plan, whether they
    fit or not, or a second "not very serious" BC break will be needed.
    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'm not sure why those would particularly need exception handling any
    more than existing language features (is calling a function with a
    non-existent named parameter that different from calling a non-existent
    function?) but that's probably been discussed elsewhere. I would be
    interested to know though, hypothetically, if PHP did not have
    exceptions at all, do you think you'd feel it couldn't have named
    arguments until they were added?

    --
    Rowan Collins
    [IMSoP]
  • Nikita Popov at Oct 27, 2013 at 3:51 pm

    On Sun, Oct 27, 2013 at 2:47 PM, Rowan Collins wrote:
    On 26/10/2013 22:40, Nikita Popov wrote:

    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.
    As I understand it, the current release process doesn't say anything about
    "big" or "major" BC breaks, but that minor releases should not break BC *at
    all*. There may be justification for relaxing that rule, but the
    justification needs to be made.

    That's a misphrasing on behalf of the RFC. The question is always "how big
    is the break?" not "is there a break?". The latter question doesn't even
    make sense because any change to PHP - including the most trivial bugfixes
    - breaks compatibility to *some* degree (well, unless the change is "fix
    whitespace in foo.c") Obligatory XKCD: http://xkcd.com/1172/

    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.
    There's a subtlety here that could be important - a script that causes
    fatal errors *in some situations* could still work in other situations.
    This is not like allowing previously invalid syntax, where an entire file
    would previously have failed to compile, these are fundamentally run-time
    behaviours, even if they *should* never happen.

    My point here was that you can only see a change in cases where the program
    already doesn't work correctly. If your code ran fine beforehand, it will
    continue to do so. Imho that's the most important bit as far as
    compatibility is concerned (to keep working code working).

    I think the comment you're referring to was mine [
    http://php.markmail.org/message/n3aw4kqhclwvpsvs] so I'll expand on it a
    little.

    Ignoring catch-all blocks, to which BaseException is a trivial
    solution/workaround, part of the stated advantage of this change is that
    finally blocks and destructors will run if a fatal error occurs. That means
    that code is running in an application state which was previously
    impossible (except for in the very limited case of the shutdown handler).

    For instance, if a mis-configured deployment meant that a particular class
    could not be autoloaded, that would previously have halted all code as soon
    as an attempt was made to use it. With an exception model, however, finally
    blocks and destructors, which might themselves rely on that class in some
    subtle way, would attempt to run. Hopefully, this wouldn't cause anything
    other than a pile of further errors - it might even transparently increase
    robustness - but it's not impossible to imagine a situation where such an
    application state would corrupt data or expose a security flaw.

    I don't know whether to consider this a "major" or "serious" change in
    behaviour, let alone whether it would generally be "good" or "bad", but it
    is a change in behaviour.

    Yes, of course behavior changes in some way - that's kind of stating the
    obvious. I wouldn't be writing an RFC if I just wanted to keep everything
    exactly as is. See the first paragraph again: Knowing that there is a
    change doesn't help us at all (because its there by definition), the only
    interesting question is how severe it is. Maybe some context will help
    here: We already changed the behavior of destructors in relation to fatal
    errors once - and that was during a bugfix release :)

    As such I don't think pushing this off to PHP 6 is justified.
    It feels like there's an assumption here that PHP 6 is a long way away.
    Rather than seeing it as pushing this feature away, it could be seen as
    pulling a major release closer. See e.g. Ferenc's suggestion to create
    separate branches for next-minor and next-major: http://php.markmail.org/*
    *message/v4gzpnfn7x6xonjs<http://php.markmail.org/message/v4gzpnfn7x6xonjs>
    Yes, my comments are under the assumption that PHP 6 won't be there anytime
    soon. Of course, if people suddenly decide that PHP 5.6 should really be
    PHP 6, then there would be little to argue about ^^ Unless we have
    *concrete* plans regarding PHP 6 saying "this should go into (a
    hypothetical, non-existing) PHP 6" is roughly equivalent to just declining
    the feature.

    PHP 6 only makes sense to me if we're planning to actually do changes with
    major BC impact. Not things like this RFC, but changes of basic language
    semantics (like fixing the 0 == "foo" comparison and other foundational
    issues).

    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'm not sure why those would particularly need exception handling any more
    than existing language features (is calling a function with a non-existent
    named parameter that different from calling a non-existent function?) but
    that's probably been discussed elsewhere. I would be interested to know
    though, hypothetically, if PHP did not have exceptions at all, do you think
    you'd feel it couldn't have named arguments until they were added?
    Especially the named arguments RFC introduces a very big slurry of
    (completely inappropriate) warnings. I don't like that and would much
    prefer to properly handle things. Of course, many people don't really care
    about error conditions, so I might continue those proposals even without
    exceptions, but I'm not really sure about that.

    Nikita
  • Pierre Joye at Oct 27, 2013 at 4:03 pm

    On Sun, Oct 27, 2013 at 4:51 PM, Nikita Popov wrote:

    Yes, my comments are under the assumption that PHP 6 won't be there anytime
    soon. Of course, if people suddenly decide that PHP 5.6 should really be
    PHP 6,
    Really not. As of now, we have enough materials for a 5.6 and a 6.x
    development will most likely take 1-2 years (no, we won't let it go
    over many years). But 6.x discussions are a bit off topic, except
    about when should we allow general exceptions usage in the core :)
    then there would be little to argue about ^^ Unless we have
    *concrete* plans regarding PHP 6 saying "this should go into (a
    hypothetical, non-existing) PHP 6" is roughly equivalent to just declining
    the feature.

    PHP 6 only makes sense to me if we're planning to actually do changes with
    major BC impact. Not things like this RFC, but changes of basic language
    semantics (like fixing the 0 == "foo" comparison and other foundational
    issues).
    I disagree here, with both your comment about the relevance of this
    RFC and what should be a 6.0.

    I like the idea to move to exception, optionally. But I do not like
    the idea to have them in one single place, and do not allow them in
    extensions or other part of the engine. Moving to exceptions usage in
    the core should be well designed and planed, and globally. This will
    be something much harder and longer to do than what is proposed here.


    Cheers,
    --
    Pierre

    @pierrejoye | http://www.libgd.org
  • Rowan Collins at Oct 27, 2013 at 4:11 pm

    On 27/10/2013 15:51, Nikita Popov wrote:

    Unless we have *concrete* plans regarding PHP 6 saying "this should go
    into (a hypothetical, non-existing) PHP 6" is roughly equivalent to
    just declining the feature.
    I agree with that, and think it is a real problem, but there are two
    solutions: abandon the BC rules for 5.x releases, or make some concrete
    plans for 6.x.

    Otherwise, the release process might as well not distinguish minor and
    major releases at all, and just define what is and isn't allowed in
    terms of BC for the foreseeable future of PHP.
    PHP 6 only makes sense to me if we're planning to actually do changes
    with major BC impact. Not things like this RFC, but changes of basic
    language semantics (like fixing the 0 == "foo" comparison and other
    foundational issues).
    Not every major release has to fix everything. An overhaul of error
    handling, in general, would seem like a good Big Feature to pin a major
    release on, just as Unicode strings would have been, had it gone ahead.

    --
    Rowan Collins
    [IMSoP]
  • Pierre Joye at Oct 27, 2013 at 7:08 pm

    On Sun, Oct 27, 2013 at 5:11 PM, Rowan Collins wrote:
    On 27/10/2013 15:51, Nikita Popov wrote:

    Unless we have *concrete* plans regarding PHP 6 saying "this should go
    into (a hypothetical, non-existing) PHP 6" is roughly equivalent to just
    declining the feature.
    Not sure where Nikita posted that, so I will comment here :)

    No, it is about defining what is good in 5.x and what is good for a
    future 6.x. Also the 6.x discussion should be taken in a separate
    thread. But I won't suggest to do it now, let keep us focused on
    getting 5.6 out in time > decide what goes in 5.6.
    I agree with that, and think it is a real problem, but there are two
    solutions: abandon the BC rules for 5.x releases, or make some concrete
    plans for 6.x.
    It is not the time now to make plan for 6.x. But to decide what goes
    in 5.6 or not.
    Otherwise, the release process might as well not distinguish minor and major
    releases at all, and just define what is and isn't allowed in terms of BC
    for the foreseeable future of PHP.
    That's what it does, both parts. And we can develop a 6.x branch in
    parallel to 5.x, f.e. 5.6.x and 5.7. The key here is to decide what
    are the key big changes we want in (tsrm drop, TLS support, general
    exceptions usage could be some of them).

    Cheers.
    --
    Pierre

    @pierrejoye | http://www.libgd.org
  • Rowan Collins at Oct 27, 2013 at 7:21 pm

    On 27/10/2013 19:08, Pierre Joye wrote:
    It is not the time now to make plan for 6.x. But to decide what goes
    in 5.6 or not.
    I don't think the two can be completely separated. If there were plans
    for over-hauling error handling in 6.x, those plans could affect
    decisions in 5.6; if there is definitely no will for such an over-haul,
    or for 6.x even existing in the foreseeable future, that makes small
    changes in 5.6 more attractive.

    --
    Rowan Collins
    [IMSoP]
  • Rowan Collins at Oct 27, 2013 at 7:15 pm

    On 27/10/2013 15:51, Nikita Popov wrote:
    The question is always "how big is the break?" not "is there a
    break?". The latter question doesn't even make sense because any
    change to PHP - including the most trivial bugfixes - breaks
    compatibility to *some* degree (well, unless the change is "fix
    whitespace in foo.c") Obligatory XKCD: http://xkcd.com/1172/
    A fair point, and trust Randall to be the one to capture its essence.

    I guess the question then is, if the changes are so minor, are the
    benefits actually any bigger than the drawbacks? As part of a move
    towards changing error handling in general, it's a good idea, but that
    implies it is the first milestone in some larger plan, which doesn't
    seem to be the case as yet.

    --
    Rowan Collins
    [IMSoP]
  • Joe Watkins at Oct 24, 2013 at 7:27 pm

    On 10/24/2013 06:41 PM, Nikita Popov wrote:
    Hi internals!

    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.

    Thoughts?

    Thanks,
    Nikita
    Delicious, obviously ...

    I will add that; if we are going to push forward with using exceptions
    properly, then there's internal code throwing base Exceptions objects
    and that needs to be fixed, catch(Exception $ex) will have _even less
    meaning_ than it does today if we are to throw exceptions in place of
    fatal errors.

    I have to ask the question; why stop at half way ??

    A warning does absolutely nothing for the programmer, or their code, all
    it does is warn the client, who isn't very likely to even be in contact
    with the programmer, even less likely has access to their code.

    Take the following code:

    $handle = fopen("/path/to/file", "w+");

    if ($handle) {

    }

    If there is no $handle, I have no idea why, god only knows what the
    logic looks like to detect why the failure occurred, and it doesn't have
    to be fopen, can be almost anything that doesn't throw exceptions.

    So, even though, some previously called function or method almost
    certainly has some information that is useful, I have to make more sys
    or library calls to determine the nature of the error and the code path
    to take.

    try {
      $handle = fopen ("/path/to/file", "w+");


    } catch (FileNotFoundException $fnf) {

    } catch (PermissionException $pex) {

    } catch (DiskFullException $dfe) {

    }

    [Note: the names of the exceptions and functions used _do not matter_,
    consider the pattern only]

    This solution has existed for years, why do we shy away from it so much
    ?? I've never heard a really good argument for the existence of warnings
    or notices at all.

    This is all said with the knowledge that some errors are truly fatal,
    there is no point to, or chance of, throwing an exception.

    +1 on the whole idea, however far we are able to take it ... the further
    the better in my opinion ...

    Cheers
    Joe
  • Nikita Popov at Oct 24, 2013 at 7:40 pm

    On Thu, Oct 24, 2013 at 9:27 PM, Joe Watkins wrote:

    I have to ask the question; why stop at half way ??

    A warning does absolutely nothing for the programmer, or their code, all
    it does is warn the client, who isn't very likely to even be in contact
    with the programmer, even less likely has access to their code.

    [...]

    This solution has existed for years, why do we shy away from it so much ??
    I've never heard a really good argument for the existence of warnings or
    notices at all.

    This is all said with the knowledge that some errors are truly fatal,
    there is no point to, or chance of, throwing an exception.

    +1 on the whole idea, however far we are able to take it ... the further
    the better in my opinion ...
    Changing existing warnings to exceptions would be a (massive) compatibility
    break. Changing fatal errors isn't (in first order approximation) because -
    well, they are fatal, you can't really depend on their behavior unless you
    are using them as a die-substitute or something ^^

    As this RFC is aimed at the 5.x branch it needs to maintain BC to a
    reasonable level, so changing warnings is really out of its scope. If you
    want to change warnings to exceptions that should be a separate proposal
    targeted at PHP 6. I'd prefer to keep it out of this thread.

    Thanks,
    Nikita
  • Joe Watkins at Oct 24, 2013 at 7:45 pm
    Okay that's reasonable enough ... Baby steps :)

    Cheers
    Joe
    On 24 Oct 2013 20:40, "Nikita Popov" wrote:
    On Thu, Oct 24, 2013 at 9:27 PM, Joe Watkins wrote:

    I have to ask the question; why stop at half way ??

    A warning does absolutely nothing for the programmer, or their code, all
    it does is warn the client, who isn't very likely to even be in contact
    with the programmer, even less likely has access to their code.

    [...]

    This solution has existed for years, why do we shy away from it so much
    ?? I've never heard a really good argument for the existence of warnings or
    notices at all.

    This is all said with the knowledge that some errors are truly fatal,
    there is no point to, or chance of, throwing an exception.

    +1 on the whole idea, however far we are able to take it ... the further
    the better in my opinion ...
    Changing existing warnings to exceptions would be a (massive)
    compatibility break. Changing fatal errors isn't (in first order
    approximation) because - well, they are fatal, you can't really depend on
    their behavior unless you are using them as a die-substitute or something ^^

    As this RFC is aimed at the 5.x branch it needs to maintain BC to a
    reasonable level, so changing warnings is really out of its scope. If you
    want to change warnings to exceptions that should be a separate proposal
    targeted at PHP 6. I'd prefer to keep it out of this thread.

    Thanks,
    Nikita
  • Pierre Joye at Oct 24, 2013 at 7:35 pm

    On Thu, Oct 24, 2013 at 7:41 PM, Nikita Popov wrote:
    Hi internals!

    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.

    Thoughts?
    I like the idea, well done!

    I understand that this RFC refers to the engine only, however I think
    many exts may follow this path too. We should consider about naming
    conventions for the extensions as well.

    Another point, I'm wondering if 5.x is the right time to introduce
    exceptions in core.

    --
    Pierre

    @pierrejoye | http://www.libgd.org
  • Andrea Faulds at Oct 24, 2013 at 7:39 pm

    On 24/10/2013 18:41, Nikita Popov wrote:
    Hi internals!

    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.

    Thoughts?

    Thanks,
    Nikita
    I love this proposal! Errors are a very dated way of handling errors,
    and there are a lot of fatal errors which are unnecessarily fatal. This
    would mean many could stop being fatal and start being exceptions, which
    is great news.

    --
    Andrea Faulds
    http://ajf.me/
  • Stas Malyshev at Oct 24, 2013 at 7:57 pm
    Hi!

    Looking at the patch, it converts zend_error_noreturn into
    ZEND_IMPOSSIBLE, which is nothing in non-debug mode. This means code
    that expected that execution ceases it this point (and jumps to a safe
    bail-out point) now just continues in non-debug mode (probably causing
    crash or memory corruption) or exits the process on failed assert in
    debug mode. I'm not sure it is a good idea to do this. A lot of code
    assumes execution does not proceed past E_ERROR, but exceptions do not
    work that way.
    --
    Stanislav Malyshev, Software Architect
    SugarCRM: http://www.sugarcrm.com/
    (408)454-6900 ext. 227
  • Nikita Popov at Oct 24, 2013 at 8:16 pm

    On Thu, Oct 24, 2013 at 9:57 PM, Stas Malyshev wrote:

    Hi!

    Looking at the patch, it converts zend_error_noreturn into
    ZEND_IMPOSSIBLE, which is nothing in non-debug mode. This means code
    that expected that execution ceases it this point (and jumps to a safe
    bail-out point) now just continues in non-debug mode (probably causing
    crash or memory corruption) or exits the process on failed assert in
    debug mode. I'm not sure it is a good idea to do this.

    To make sure that there are no misunderstandings, Stas is referring to two
    particular occurrences where E_ERROR has been replaced with a
    ZEND_IMPOSSIBLE macro. Both occurrences are unreachable code (or so I
    judged), so they are effectively assertions implemented using E_ERROR
    rather than assert(). The ZEND_IMPOSSIBLE macro is a more explicit way of
    saying assert(0). PHP removes assertions in non-debug builds
    (optimization), so this follows suit.

    I did not mention this in the RFC because I'm not yet sure this change is
    necessary and I might yet keep them as (pointless) fatal errors instead,
    just in case. This is mainly a note to myself that I looked at the error
    and decided that it does not require conversion.

    A lot of code assumes execution does not proceed past E_ERROR, but
    exceptions do not work that way.
    >

    That's correct. In the places where I replaced fatal errors with exceptions
    I make sure to free resources and handle the exception.

    Nikita
  • Larry Garfield at Oct 24, 2013 at 10:31 pm

    On 10/24/13 12:41 PM, Nikita Popov wrote:
    Hi internals!

    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.

    Thoughts?

    Thanks,
    Nikita
    As a PHP user-space developer I love this idea. However, I share the
    concern of others here that it could result in BC unpleasantness, even
    if limited to the E_FATAL and E_RECOVERABLE_FATAL use cases. I don't
    know off hand how various versions of Drupal would handle this.

    --Larry Garfield
  • Joe Watkins at Oct 25, 2013 at 1:02 pm

    On 10/24/2013 11:31 PM, Larry Garfield wrote:
    On 10/24/13 12:41 PM, Nikita Popov wrote:
    Hi internals!

    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.

    Thoughts?

    Thanks,
    Nikita
    As a PHP user-space developer I love this idea. However, I share the
    concern of others here that it could result in BC unpleasantness, even
    if limited to the E_FATAL and E_RECOVERABLE_FATAL use cases. I don't
    know off hand how various versions of Drupal would handle this.

    --Larry Garfield
    How could anything be reliant on the behaviour of a fatal error in any
    meaningful way ??

    Cheers
    Joe
  • Richard Bradley at Oct 25, 2013 at 1:56 pm

    -----Original Message-----
    From: Joe Watkins
    Sent: 25 October 2013 14:02
    To: internals@lists.php.net; Larry Garfield
    Subject: Re: [PHP-DEV] [RFC] Exceptions in the engine
    On 10/24/2013 11:31 PM, Larry Garfield wrote:
    On 10/24/13 12:41 PM, Nikita Popov wrote:
    Hi internals!

    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.

    Thoughts?

    Thanks,
    Nikita
    As a PHP user-space developer I love this idea. However, I share the
    concern of others here that it could result in BC unpleasantness, even
    if limited to the E_FATAL and E_RECOVERABLE_FATAL use cases. I don't
    know off hand how various versions of Drupal would handle this.

    --Larry Garfield
    How could anything be reliant on the behaviour of a fatal error in any meaningful way ??

    Cheers
    Joe
    In plenty of ways: for example currently frameworks can "catch" fatal errors using "register_shutdown_function" and display an error page to the end user (say if there is an attempt to call a method on a null object due to an unanticipated runtime error).

    Current frameworks might be broken if the way fatal errors work is changed. That would be a BC break.

    See e.g. http://stackoverflow.com/questions/16284235/zend-framework-error-page-for-php-fatal-errors/16284260#16284260

    (This is not a vote for or against this proposal; I'm just answering the immediate parent here.)

    Best,


    Rich





    Richard Bradley
    Tel : 020 7485 7500 ext 3230 | Fax : 020 7485 7575

    softwire
    Sunday Times Best Small Companies - UK top 20 three years running
    Web : www.softwire.com | Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL
    Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB
  • Jordi Boggiano at Oct 25, 2013 at 2:03 pm

    On Fri, Oct 25, 2013 at 3:55 PM, Richard Bradley wrote:
    How could anything be reliant on the behaviour of a fatal error in any meaningful way ??

    Cheers
    Joe
    In plenty of ways: for example currently frameworks can "catch" fatal errors using "register_shutdown_function" and display an error page to the end user (say if there is an attempt to call a method on a null object due to an unanticipated runtime error).

    Current frameworks might be broken if the way fatal errors work is changed. That would be a BC break.

    See e.g. http://stackoverflow.com/questions/16284235/zend-framework-error-page-for-php-fatal-errors/16284260#16284260

    (This is not a vote for or against this proposal; I'm just answering the immediate parent here.)
    Wouldn't this sort of use case be covered by the fact that an uncaught
    exception would still result in a fatal error? The only case it'd
    "break" is if you have a try/catch around your entire application,
    before you had to listen to have a shutdown handler but now your catch
    would catch the fatal exceptions before they bring everything down.
    I'd imagine that this RFC would not affect most sane cases of shutdown
    handlers and related "show a nice error page to users when all hell
    breaks loose" tricks.

    Cheers

    --
    Jordi Boggiano
    @seldaek - http://nelm.io/jordi
  • Richard Bradley at Oct 25, 2013 at 2:09 pm

    -----Original Message-----
    From: Jordi Boggiano
    Sent: 25 October 2013 15:03
    To: Richard Bradley
    Cc: Joe Watkins; internals@lists.php.net; Larry Garfield
    Subject: Re: [PHP-DEV] [RFC] Exceptions in the engine
    On Fri, Oct 25, 2013 at 3:55 PM, Richard Bradley wrote:
    How could anything be reliant on the behaviour of a fatal error in any meaningful way ??

    Cheers
    Joe
    In plenty of ways: for example currently frameworks can "catch" fatal errors using "register_shutdown_function" and display an error page to the end user (say if there is an attempt to call a method on a null object due to an unanticipated runtime error).

    Current frameworks might be broken if the way fatal errors work is changed. That would be a BC break.

    See e.g.
    http://stackoverflow.com/questions/16284235/zend-framework-error-page-
    for-php-fatal-errors/16284260#16284260

    (This is not a vote for or against this proposal; I'm just answering
    the immediate parent here.)
    Wouldn't this sort of use case be covered by the fact that an uncaught exception would still result in a fatal error? The only case it'd "break" is if you have a try/catch around your entire application, before you had to listen to have a shutdown handler but now your catch would catch the fatal exceptions before they bring everything down.
    You might still end up in the register_shutdown_function yes, but the error code would have changed (from error_get_last())
    i.e. people may well be relying on the exact behaviour of fatal errors.

    It would be great to fix the somewhat messy state of exceptions & errors in PHP, but we shouldn't pretend that we can do so without BC breaks.





    Richard Bradley
    Tel : 020 7485 7500 ext 3230 | Fax : 020 7485 7575

    softwire
    Sunday Times Best Small Companies - UK top 20 three years running
    Web : www.softwire.com | Addr : 325 Highgate Studios, 53-79 Highgate Road, London NW5 1TL
    Softwire Technology Limited. Registered in England no. 3824658. Registered Office : 13 Station Road, London N3 2SB
  • George Bond at Oct 25, 2013 at 3:00 pm

    On 25 October 2013 15:09, Richard Bradley wrote:

    -----Original Message-----
    From: Jordi Boggiano
    Sent: 25 October 2013 15:03
    To: Richard Bradley
    Cc: Joe Watkins; internals@lists.php.net; Larry Garfield
    Subject: Re: [PHP-DEV] [RFC] Exceptions in the engine

    On Fri, Oct 25, 2013 at 3:55 PM, Richard Bradley <
    richard.bradley@softwire.com> wrote:
    How could anything be reliant on the behaviour of a fatal error in
    any meaningful way ??
    Cheers
    Joe
    In plenty of ways: for example currently frameworks can "catch" fatal
    errors using "register_shutdown_function" and display an error page to the
    end user (say if there is an attempt to call a method on a null object due
    to an unanticipated runtime error).
    Current frameworks might be broken if the way fatal errors work is
    changed. That would be a BC break.
    See e.g.
    http://stackoverflow.com/questions/16284235/zend-framework-error-page-
    for-php-fatal-errors/16284260#16284260

    (This is not a vote for or against this proposal; I'm just answering
    the immediate parent here.)
    Wouldn't this sort of use case be covered by the fact that an uncaught
    exception would still result in a fatal error? The only case it'd "break"
    is if you have a try/catch around your entire application, before you had
    to listen to have a shutdown handler but now your catch would catch the
    fatal exceptions before they bring everything down.

    You might still end up in the register_shutdown_function yes, but the
    error code would have changed (from error_get_last())
    i.e. people may well be relying on the exact behaviour of fatal errors.

    It would be great to fix the somewhat messy state of exceptions & errors
    in PHP, but we shouldn't pretend that we can do so without BC breaks.
    I think as far as BC breaks go, "in the event that my application has
    already become unusable to the end-user, now only the sensibly-structured
    catch-all codepath that we had to implement anyway is followed rather than
    that other much-nastier-to-work-with codepath" is pretty uncontroversial...

    --G
  • Stas Malyshev at Oct 25, 2013 at 7:20 pm
    Hi!
    How could anything be reliant on the behaviour of a fatal error in any
    meaningful way ??
    If condition X did not occur, fatal error would happen, so in the
    following code I can safely assume condition X is true without checking it.

    That logic of course would completely break with non-fatal fatal errors,
    both in C and in PHP.

    Oh yes, and people do try {...} catch(Exception e) { /* ignore
    exceptions */} all the time (without, of course, counting fatal errors
    as being ignored).

    --
    Stanislav Malyshev, Software Architect
    SugarCRM: http://www.sugarcrm.com/
    (408)454-6900 ext. 227
  • Joe Watkins at Oct 25, 2013 at 7:41 pm

    On 10/25/2013 08:20 PM, Stas Malyshev wrote:
    Hi!
    How could anything be reliant on the behaviour of a fatal error in any
    meaningful way ??
    If condition X did not occur, fatal error would happen, so in the
    following code I can safely assume condition X is true without checking it.

    That logic of course would completely break with non-fatal fatal errors,
    both in C and in PHP.

    Oh yes, and people do try {...} catch(Exception e) { /* ignore
    exceptions */} all the time (without, of course, counting fatal errors
    as being ignored).
    Catch all and error handling hacks to ignore fatals are covered in the
    RFC, I think satisfactorily, mostly ...

    I haven't really thought about it too much, it just seemed a bit silly
    to rely on what is essentially shutdown ...

    I'm liking the idea of BaseException, for this, and in general, would
    allow us to avoid the problem of catch all blocks, or at least the ones
    that are in existence now ...

    If we really wanted to, we could fix all the code that throws the base
    Exception, making them throw specialized types, as they should, and
    include a compiler check that finds catch(Exception) blocks and
    complains, it shouldn't really be valid, we could encourage people to do
    things the right way in the hope that someday we won't have to worry
    about catch all blocks when looking to make improvements ...

    Cheers
    Joe
  • Rowan Collins at Oct 26, 2013 at 12:18 pm

    On 25/10/2013 20:41, Joe Watkins wrote:
    If we really wanted to, we could fix all the code that throws the base
    Exception, making them throw specialized types, as they should
    This seems a little contradictory when you're proposing an
    undifferentiated EngineException, where individual errors would need to
    be distinguished based on the message string. That's pretty much what
    throw Exception('Some message'); gives in userland.

    Besides which...
    and include a compiler check that finds catch(Exception) blocks and
    complains, it shouldn't really be valid
    I don't think "catch(Exception)" blocks exist as a partner to "throw
    Exception;" they exist to mark a boundary in code that you don't want
    any exceptions to cross, or where you want to log all exceptions in some
    bespoke way. They might be the last in a long string of catch() blocks
    attached to one try, like the default: label in a switch statement. They
    might also, as discussed wrt assertions/expectations, be in a unit
    testing framework.

    --
    Rowan Collins
    [IMSoP]
  • Rowan Collins at Oct 26, 2013 at 12:34 pm

    On 26/10/2013 13:18, Rowan Collins wrote:
    On 25/10/2013 20:41, Joe Watkins wrote:
    If we really wanted to, we could fix all the code that throws the
    base Exception, making them throw specialized types, as they should
    This seems a little contradictory when you're proposing an
    undifferentiated EngineException
    Apologies, I'd lost track of the thread a bit - it's not you that's
    proposing that, so this paragraph is rather mis-targeted.

    --
    Rowan Collins
    [IMSoP]
  • Joe Watkins at Oct 26, 2013 at 2:26 pm

    On 10/26/2013 01:18 PM, Rowan Collins wrote:
    On 25/10/2013 20:41, Joe Watkins wrote:
    If we really wanted to, we could fix all the code that throws the base
    Exception, making them throw specialized types, as they should
    This seems a little contradictory when you're proposing an
    undifferentiated EngineException, where individual errors would need to
    be distinguished based on the message string. That's pretty much what
    throw Exception('Some message'); gives in userland.

    Besides which...
    and include a compiler check that finds catch(Exception) blocks and
    complains, it shouldn't really be valid
    I don't think "catch(Exception)" blocks exist as a partner to "throw
    Exception;" they exist to mark a boundary in code that you don't want
    any exceptions to cross, or where you want to log all exceptions in some
    bespoke way. They might be the last in a long string of catch() blocks
    attached to one try, like the default: label in a switch statement. They
    might also, as discussed wrt assertions/expectations, be in a unit
    testing framework.
    They _should_ exist as a boundary, a last resort, if at all, but when
    they do exist they are no such boundary or last resort, they are normal
    catch blocks because the core throws the base Exception ... I'm just
    making the observation that it's not a very good idea to do that,
    doesn't take a lot to fix, has no bc issues and sets the right kind of
    standard.

    An EngineException is just that, an Exception from the Engine, that
    makes sense, an Exception coming from Date, doesn't make sense, that
    should be a DateException, it's not dependant on or descended from
    EngineException at all, it would just be better form if exceptions
    thrown from the core meant something so that catch all exception blocks
    when they are used are just as we all know they should be - a last
    resort, if present at all.

    Maybe emitting a warning is a bit pedantic ...

    Anyway, carry on with the discussion at hand, which is not about any of
    this at all, I was just saying it might be nice if we are to start using
    exceptions from core _as a policy_ to make good, as good as possible,
    our use of exceptions so far.

    Cheers
    Joe
  • Rowan Collins at Oct 26, 2013 at 3:04 pm

    On 26/10/2013 15:26, Joe Watkins wrote:
    They _should_ exist as a boundary, a last resort, if at all, but when
    they do exist they are no such boundary or last resort, they are
    normal catch blocks because the core throws the base Exception ... I'm
    just making the observation that it's not a very good idea to do that,
    doesn't take a lot to fix, has no bc issues and sets the right kind of
    standard.
    Right, I'm agreed that throw statements should be as specific as
    possible, both in core/extensions and in userland.

    But you seemed to link that somehow to catch(Exception) blocks, which
    are an entirely different topic, and have valid use cases, since they
    mean "catch everything descended from this class" not "catch things with
    this exact class".

    Regards the engine throwing exceptions, it's the catch side of things
    which is most relevant.

    --
    Rowan Collins
    [IMSoP]
  • Rowan Collins at Oct 26, 2013 at 1:15 pm

    On 25/10/2013 14:02, Joe Watkins wrote:
    On 10/24/2013 11:31 PM, Larry Garfield wrote:
    As a PHP user-space developer I love this idea. However, I share the
    concern of others here that it could result in BC unpleasantness, even
    if limited to the E_FATAL and E_RECOVERABLE_FATAL use cases. I don't
    know off hand how various versions of Drupal would handle this.

    --Larry Garfield
    How could anything be reliant on the behaviour of a fatal error in any
    meaningful way ??
    I think there's an important distinction between "not breaking any
    backwards compatibility" and "breaking backwards compatibility in an
    acknowledged way having weighed the impact".

    A change is only 100% backwards compatible if an existing valid script
    would behave identically on the old and new versions, with the change
    only being visible if the programmer explicitly takes advantage of it.
    The short-hand array syntax fulfilled this requirement, to the best of
    my knowledge; the introduction of Traits didn't quite, because it
    reserved a few keywords, but that was its only impact.

    Throwing exceptions for things which were previously fatal errors will
    change the behaviour of existing scripts in several ways, some of which
    are the stated aims of the RFC:

      1. Messages previously issuing E_RECOVERABLE_ERROR will no longer
         trigger handlers registered with set_error_handler()
      2. It will no longer be possible to catch an E_RECOVERABLE_ERROR and
         continue in the same context
      3. If all uses of E_RECOVERABLE_ERROR are converted to exceptions, that
         constant will become redundant, and all uses of it, e.g. in
         error_reporting() bitmasks, will become meaningless.
      4. catch(Exception) blocks will pick up the errors, unless a
         BaseException is introduced
      5. The handler registered with set_exception_handler() will
         (presumably) be called for such errors
      6. If a BaseException *is* introduced, typehints of class Exception
         will fail for some exception objects (I spotted this noting that the
         documentation for set_exception_handler implies a callback with such
         a typehint)
      7. Finally blocks and destructors will be called when an error occurs
      8. As a consequence of the above, previously impossible codepaths and
         program states will become possible
      9. It will become possible for multiple "fatal" errors to occur in a
         single script execution, since code will continue executing after
         the first is thrown as an exception

    I don't think there can be any doubt that this change would break *some*
    backwards compatibility, even if a BaseException is introduced (which
    seems sensible) and E_RECOVERABLE_ERRORs are left untouched (which seems
    unfortunate).

    The question then becomes if it is an *acceptable* break, due to the
    behaviours affected being considered marginal enough to ignore - and
    also whether the value of having this in 5.x outweighs the cost.

    Don't get me wrong, I would love to see error handling in PHP cleaned
    up, but I'm not convinced that doing it piecemeal in non-breaking steps
    is either possible or desirable. I'd like to see this expanded into a
    fully considered mechanism which would be a fitting backbone for a major
    release.

    --
    Rowan Collins
    [IMSoP]
  • Julien Pauli at Oct 26, 2013 at 4:27 pm

    On Sat, Oct 26, 2013 at 3:14 PM, Rowan Collins wrote:
    On 25/10/2013 14:02, Joe Watkins wrote:
    On 10/24/2013 11:31 PM, Larry Garfield wrote:

    As a PHP user-space developer I love this idea. However, I share the
    concern of others here that it could result in BC unpleasantness, even
    if limited to the E_FATAL and E_RECOVERABLE_FATAL use cases. I don't
    know off hand how various versions of Drupal would handle this.

    --Larry Garfield
    How could anything be reliant on the behaviour of a fatal error in any
    meaningful way ??
    I think there's an important distinction between "not breaking any
    backwards compatibility" and "breaking backwards compatibility in an
    acknowledged way having weighed the impact".

    A change is only 100% backwards compatible if an existing valid script
    would behave identically on the old and new versions, with the change only
    being visible if the programmer explicitly takes advantage of it. The
    short-hand array syntax fulfilled this requirement, to the best of my
    knowledge; the introduction of Traits didn't quite, because it reserved a
    few keywords, but that was its only impact.

    Throwing exceptions for things which were previously fatal errors will
    change the behaviour of existing scripts in several ways, some of which are
    the stated aims of the RFC:

    1. Messages previously issuing E_RECOVERABLE_ERROR will no longer
    trigger handlers registered with set_error_handler()
    2. It will no longer be possible to catch an E_RECOVERABLE_ERROR and
    continue in the same context
    3. If all uses of E_RECOVERABLE_ERROR are converted to exceptions, that
    constant will become redundant, and all uses of it, e.g. in
    error_reporting() bitmasks, will become meaningless.
    4. catch(Exception) blocks will pick up the errors, unless a
    BaseException is introduced
    5. The handler registered with set_exception_handler() will
    (presumably) be called for such errors
    6. If a BaseException *is* introduced, typehints of class Exception
    will fail for some exception objects (I spotted this noting that the
    documentation for set_exception_handler implies a callback with such
    a typehint)
    7. Finally blocks and destructors will be called when an error occurs
    8. As a consequence of the above, previously impossible codepaths and
    program states will become possible
    9. It will become possible for multiple "fatal" errors to occur in a
    single script execution, since code will continue executing after
    the first is thrown as an exception

    I don't think there can be any doubt that this change would break *some*
    backwards compatibility, even if a BaseException is introduced (which seems
    sensible) and E_RECOVERABLE_ERRORs are left untouched (which seems
    unfortunate).

    The question then becomes if it is an *acceptable* break, due to the
    behaviours affected being considered marginal enough to ignore - and also
    whether the value of having this in 5.x outweighs the cost.

    Don't get me wrong, I would love to see error handling in PHP cleaned up,
    but I'm not convinced that doing it piecemeal in non-breaking steps is
    either possible or desirable. I'd like to see this expanded into a fully
    considered mechanism which would be a fitting backbone for a major release.

    +1 for the last ideas.

    I'm not +1 for having such a change in the 5.x branch.
    However, I'm full +1 to have this change + others (Warnings, Notices,
    etc... to exceptions), having refactored all the code ; for a 6.x branch or
    whatever major number it'll be.

    Starting trying to keep some BC, but not all, to make people half happy,
    but not too much nor less , is just a mistake, IMO. it will add confusion
    and mess in PHP, and we don't really need that :-p
    Your ideas are great, the patch is at an advanced stage , but such ideas
    and changes should definetly not go for 5.x branch.

    About next major, we have not decided yet which next version PHP will be.
    We all talked about a possible 5.6 , but if we could have a massive
    contribution wave, with great ideas like this one , then we could break BC,
    and make PHP-next a major release.

    Julien.Pauli
  • Larry Garfield at Oct 26, 2013 at 6:27 pm

    On 10/26/2013 11:26 AM, Julien Pauli wrote:
    On Sat, Oct 26, 2013 at 3:14 PM, Rowan Collins wrote:
    On 25/10/2013 14:02, Joe Watkins wrote:
    On 10/24/2013 11:31 PM, Larry Garfield wrote:

    As a PHP user-space developer I love this idea. However, I share the
    concern of others here that it could result in BC unpleasantness, even
    if limited to the E_FATAL and E_RECOVERABLE_FATAL use cases. I don't
    know off hand how various versions of Drupal would handle this.

    --Larry Garfield
    How could anything be reliant on the behaviour of a fatal error in any
    meaningful way ??
    I think there's an important distinction between "not breaking any
    backwards compatibility" and "breaking backwards compatibility in an
    acknowledged way having weighed the impact".

    A change is only 100% backwards compatible if an existing valid script
    would behave identically on the old and new versions, with the change only
    being visible if the programmer explicitly takes advantage of it. The
    short-hand array syntax fulfilled this requirement, to the best of my
    knowledge; the introduction of Traits didn't quite, because it reserved a
    few keywords, but that was its only impact.

    Throwing exceptions for things which were previously fatal errors will
    change the behaviour of existing scripts in several ways, some of which are
    the stated aims of the RFC:

    1. Messages previously issuing E_RECOVERABLE_ERROR will no longer
    trigger handlers registered with set_error_handler()
    2. It will no longer be possible to catch an E_RECOVERABLE_ERROR and
    continue in the same context
    3. If all uses of E_RECOVERABLE_ERROR are converted to exceptions, that
    constant will become redundant, and all uses of it, e.g. in
    error_reporting() bitmasks, will become meaningless.
    4. catch(Exception) blocks will pick up the errors, unless a
    BaseException is introduced
    5. The handler registered with set_exception_handler() will
    (presumably) be called for such errors
    6. If a BaseException *is* introduced, typehints of class Exception
    will fail for some exception objects (I spotted this noting that the
    documentation for set_exception_handler implies a callback with such
    a typehint)
    7. Finally blocks and destructors will be called when an error occurs
    8. As a consequence of the above, previously impossible codepaths and
    program states will become possible
    9. It will become possible for multiple "fatal" errors to occur in a
    single script execution, since code will continue executing after
    the first is thrown as an exception

    I don't think there can be any doubt that this change would break *some*
    backwards compatibility, even if a BaseException is introduced (which seems
    sensible) and E_RECOVERABLE_ERRORs are left untouched (which seems
    unfortunate).

    The question then becomes if it is an *acceptable* break, due to the
    behaviours affected being considered marginal enough to ignore - and also
    whether the value of having this in 5.x outweighs the cost.

    Don't get me wrong, I would love to see error handling in PHP cleaned up,
    but I'm not convinced that doing it piecemeal in non-breaking steps is
    either possible or desirable. I'd like to see this expanded into a fully
    considered mechanism which would be a fitting backbone for a major release.
    +1 for the last ideas.

    I'm not +1 for having such a change in the 5.x branch.
    However, I'm full +1 to have this change + others (Warnings, Notices,
    etc... to exceptions), having refactored all the code ; for a 6.x branch or
    whatever major number it'll be.

    Starting trying to keep some BC, but not all, to make people half happy,
    but not too much nor less , is just a mistake, IMO. it will add confusion
    and mess in PHP, and we don't really need that :-p
    Your ideas are great, the patch is at an advanced stage , but such ideas
    and changes should definetly not go for 5.x branch.

    About next major, we have not decided yet which next version PHP will be.
    We all talked about a possible 5.6 , but if we could have a massive
    contribution wave, with great ideas like this one , then we could break BC,
    and make PHP-next a major release.

    Julien.Pauli
    I have to agree with both of these.

    "It's a BC break but we've weighed it and decided it's OK" may sound
    good, but it's one of the key reasons that this is still the case:

    http://w3techs.com/technologies/details/pl-php/5/all

    There are more users of PHP 5.1 than there are of 5.5, and 5.4 is still
    less than 10% of the market. 5.3, already EOLed, only just recently
    surpassed 5.2 this year.

    This is why we (user-space developers) can't have nice things. :-) New
    versions of PHP have very nice things, but mass-market hosts, sysadmins,
    and anyone else with legacy code is extremel squeamish about upgrading
    to new PHP versions for fear of breaking things. That holds back the
    whole industry.

    I'd love to switch to exceptions properly in PHP, but I think it's
    better done as part of a for-reals switch to PHP 6, where some
    BC-breaking changes are allowed but cross-version compatibility is still
    possible. (As was the case with PHP 4->PHP5. "Well behaved" code from
    PHP 4.4 can still run today on 5.5, but the definition of "well behaved"
    wasn't necessarily known at the time of 4.2. It needs to be possible to
    write code that runs properly in both 5.late and 6.x, or no one will
    switch to 6.x)

    Back on topic then... +1 to engine level exceptions... in PHP 6. Which
    should happen sooner rather than later.

    --Larry Garfield
  • Alexey Zakhlestin at Oct 25, 2013 at 9:59 am

    On 24 окт. 2013 г., at 21:41, Nikita Popov 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.

    Thoughts?
    Thank you, Nikita!
    That’s something which definitely needs to be done.

    Catching parse-errors from includes, bad function/method calls, etc. will let us make complex code-bases more robust and predictable.

    I think introduction of BaseException is a necessity.
    This way code will stay compatible and new exceptions will just end their life somewhere in shutdown-handler, just as fatal errors do now.

    Rowan proposed to use subclasses for different exception types — I believe it can wait a bit. There is no need to overcomplicate this.
    New classes would be added eventually, but as they will be extending EngineException forward-compatibility is preserved.

    converting fatal-errors is a safe-enough change to be done in 5.NEXT.

    converting some of the warnings is a good topic for starting 6.x
  • Clint Priest at Oct 26, 2013 at 7:23 pm

    On 10/24/2013 12:41 PM, Nikita Popov wrote:
    https://wiki.php.net/rfc/engine_exceptions
    Very nice Nikita...

    I like that this patch would provide for very little BC breakage. Given
    Rowan's list, there would be some changes in behavior but I think that
    the behavior would be desirable for those that have written their code
    in this manner (that finally's and destructors will be called, etc).

    It might even be likely that those who have written code in this manner
    are not aware that their code isn't being unwound properly, I've run
    across situations like this before and am always a little leery of
    writing code that relies on destructors being called since it is not
    perfectly reliable.

    On the potential issues:
       +1 for BaseException
       -1 for E_RECOVERABLE becoming exceptions because of the BC breakage
    (execution flow should continue on the next line)
       +1 for the final error message being reduced to Uncaught
    EngineException...
       -1 for not all errors converted, if it's an error that occurs after
    code execution has begun then they should all be converted for consistency.

    On other ideas presented as comments:
       -1 for changing any current errors that let code execution continue
    (E_WARNING, E_NOTICE, etc) into exceptions.

    In the end, I think that the current RFC takes it to where it really
    needs to be: proper unwinding of finally/destructors, better uncaught
    fatal error information (stack traces). Some other languages go way too
    far with exceptions and make writing anything in them consist of 30% of
    the code being try/catch blocks rather than real code.

    The only thing I would suggest is that it not being a single
    EngineException, but a few well thought out sub-classes of EngineException.

    -Clint
  • Joe Watkins at Oct 26, 2013 at 8:48 pm

    On 10/26/2013 08:23 PM, Clint Priest wrote:
    On 10/24/2013 12:41 PM, Nikita Popov wrote:
    https://wiki.php.net/rfc/engine_exceptions
    The only thing I would suggest is that it not being a single
    EngineException, but a few well thought out sub-classes of EngineException.

    -Clint
    Actually this does make sense when you think about it ...

    So +1 to that ...

    I've still not really managed to organize all my thoughts into a
    coherent opinion on the things brought up, I'm not sure I see the major
    BC issues that other people do.

    Like Clint has mentioned this is as far as it needs to go now, I think
    that's probably where I'm at ...

    Cheers

Related Discussions

People

Translate

site design / logo © 2022 Grokbase