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
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
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:
-
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.) -
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 byset_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
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]
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:
- 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... - 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
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 (withE_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:
- 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...- 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
--
Alexey Zakhlestin
CTO at Grids.by/you
https://github.com/indeyets
PGP key: http://indeyets.ru/alexey.zakhlestin.pgp.asc
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 (withE_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]
On Sun, Oct 27, 2013 at 2:47 PM, Rowan Collins rowan.collins@gmail.comwrote:
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 (withE_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/v4gzpnfn7x6xonjshttp://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
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
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]
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
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]
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]
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
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
Okay that's reasonable enough ... Baby steps :)
Cheers
Joe
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
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
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/
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
On Thu, Oct 24, 2013 at 9:57 PM, Stas Malyshev smalyshev@sugarcrm.comwrote:
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
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
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,
NikitaAs 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
-----Original Message-----
From: Joe Watkins [mailto:krakjoe@php.net]
Sent: 25 October 2013 14:02
To: internals@lists.php.net; Larry Garfield
Subject: Re: [PHP-DEV] [RFC] Exceptions in the engineHi 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,
NikitaAs 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.
(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
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
JoeIn 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.
(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
-----Original Message-----
From: Jordi Boggiano [mailto:j.boggiano@seld.be]
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 engineHow could anything be reliant on the behaviour of a fatal error in any meaningful way ??
Cheers
JoeIn 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
On 25 October 2013 15:09, Richard Bradley Richard.Bradley@softwire.comwrote:
-----Original Message-----
From: Jordi Boggiano [mailto:j.boggiano@seld.be]
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 engineOn 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
JoeIn 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 (fromerror_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
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
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
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]
If we really wanted to, we could fix all the code that throws the
base Exception, making them throw specialized types, as they shouldThis 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]
If we really wanted to, we could fix all the code that throws the base
Exception, making them throw specialized types, as they shouldThis 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 validI 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
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]
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:
- Messages previously issuing
E_RECOVERABLE_ERROR
will no longer
trigger handlers registered withset_error_handler()
- It will no longer be possible to catch an
E_RECOVERABLE_ERROR
and
continue in the same context - 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. - catch(Exception) blocks will pick up the errors, unless a
BaseException is introduced - The handler registered with
set_exception_handler()
will
(presumably) be called for such errors - 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) - Finally blocks and destructors will be called when an error occurs
- As a consequence of the above, previously impossible codepaths and
program states will become possible - 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]
On Sat, Oct 26, 2013 at 3:14 PM, Rowan Collins rowan.collins@gmail.comwrote:
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:
- Messages previously issuing
E_RECOVERABLE_ERROR
will no longer
trigger handlers registered withset_error_handler()
- It will no longer be possible to catch an
E_RECOVERABLE_ERROR
and
continue in the same context- 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.- catch(Exception) blocks will pick up the errors, unless a
BaseException is introduced- The handler registered with
set_exception_handler()
will
(presumably) be called for such errors- 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)- Finally blocks and destructors will be called when an error occurs
- As a consequence of the above, previously impossible codepaths and
program states will become possible- 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 exceptionI 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
On Sat, Oct 26, 2013 at 3:14 PM, Rowan Collins rowan.collins@gmail.comwrote:
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:
- Messages previously issuing
E_RECOVERABLE_ERROR
will no longer
trigger handlers registered withset_error_handler()
- It will no longer be possible to catch an
E_RECOVERABLE_ERROR
and
continue in the same context- 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.- catch(Exception) blocks will pick up the errors, unless a
BaseException is introduced- The handler registered with
set_exception_handler()
will
(presumably) be called for such errors- 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)- Finally blocks and destructors will be called when an error occurs
- As a consequence of the above, previously impossible codepaths and
program states will become possible- 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 exceptionI 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
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
--
Alexey Zakhlestin
CTO at Grids.by/you
https://github.com/indeyets
PGP key: http://indeyets.ru/alexey.zakhlestin.pgp.asc
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
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