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/v4gzpnfn7x6xonjsThe 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]