# [RFC] Exceptions in the engine

- Thread: https://externals.io/message/69847
- Original archive: https://news-web.php.net/php.internals/69847
- Started by Nikita Popov on 2013-10-24T17:41:29+00:00
- Messages: 38
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/69847.md?page=2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #69847 — Nikita Popov — 2013-10-24T17:41:29+00:00

URL: https://externals.io/message/69847#69847

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

---

## #69848 — johannes@schlueters.de — 2013-10-24T17:56:55+00:00

URL: https://externals.io/message/69847#69848 · In reply to: #69847

> 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

---

## #69849 — Adam Harvey — 2013-10-24T18:01:06+00:00

URL: https://externals.io/message/69847#69849 · In reply to: #69847

> 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

---

## #69850 — Joe Watkins — 2013-10-24T19:27:42+00:00

URL: https://externals.io/message/69847#69850 · In reply to: #69847

> 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

---

## #69851 — Pierre Joye — 2013-10-24T19:35:31+00:00

URL: https://externals.io/message/69847#69851 · In reply to: #69847

> 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

---

## #69852 — Andrea Faulds — 2013-10-24T19:39:41+00:00

URL: https://externals.io/message/69847#69852 · In reply to: #69847

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

---

## #69853 — Nikita Popov — 2013-10-24T19:40:28+00:00

URL: https://externals.io/message/69847#69853 · In reply to: #69850

> 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

---

## #69854 — Joe Watkins — 2013-10-24T19:45:18+00:00

URL: https://externals.io/message/69847#69854 · In reply to: #69853

Okay that's reasonable enough ... Baby steps :)

Cheers
Joe


> 
>
> > […]
>
> 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

---

## #69855 — Stas Malyshev — 2013-10-24T19:57:35+00:00

URL: https://externals.io/message/69847#69855 · In reply to: #69847

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

---

## #69856 — Nikita Popov — 2013-10-24T20:16:27+00:00

URL: https://externals.io/message/69847#69856 · In reply to: #69855

On Thu, Oct 24, 2013 at 9:57 PM, Stas Malyshev <smalyshev@sugarcrm.com>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

---

## #69857 — Rowan Collins — 2013-10-24T20:28:18+00:00

URL: https://externals.io/message/69847#69857 · In reply to: #69849

> 
> > […]
> 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]

---

## #69859 — Larry Garfield — 2013-10-24T22:31:17+00:00

URL: https://externals.io/message/69847#69859 · In reply to: #69847

> 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

---

## #69863 — Alexey Zakhlestin — 2013-10-25T09:59:11+00:00

URL: https://externals.io/message/69847#69863 · In reply to: #69847

> 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

---

## #69864 — Joe Watkins — 2013-10-25T13:02:04+00:00

URL: https://externals.io/message/69847#69864 · In reply to: #69859

> 
> > […]
>
> 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

---

## #69865 — Richard Bradley — 2013-10-25T13:55:50+00:00

URL: https://externals.io/message/69847#69865 · In reply to: #69864

> -----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 engine
>
> 
> > […]
>
> 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

---

## #69866 — Jordi Boggiano — 2013-10-25T14:03:17+00:00

URL: https://externals.io/message/69847#69866 · In reply to: #69865

On Fri, Oct 25, 2013 at 3:55 PM, Richard Bradley
<Richard.Bradley@softwire.com> wrote:
> > […]
>
> 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

---

## #69867 — Richard Bradley — 2013-10-25T14:09:16+00:00

URL: https://externals.io/message/69847#69867 · In reply to: #69866

> -----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 engine
>
> 
> > […]
>
> 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

---

## #69868 — George Bond — 2013-10-25T15:00:15+00:00

URL: https://externals.io/message/69847#69868 · In reply to: #69867

On 25 October 2013 15:09, Richard Bradley <Richard.Bradley@softwire.com>wrote:

> > […]
> Richard.Bradley@softwire.com> wrote:
> > […]
> any meaningful way ??
> > […]
> 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).
> > […]
> changed. That would be a BC break.
> > […]
> 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

---

## #69870 — Stas Malyshev — 2013-10-25T19:20:18+00:00

URL: https://externals.io/message/69847#69870 · In reply to: #69864

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

---

## #69871 — Joe Watkins — 2013-10-25T19:41:04+00:00

URL: https://externals.io/message/69847#69871 · In reply to: #69870

> Hi!
>
> > […]
>
> 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

---

## #69875 — Rowan Collins — 2013-10-26T12:18:17+00:00

URL: https://externals.io/message/69847#69875 · In reply to: #69871

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

---

## #69876 — Rowan Collins — 2013-10-26T12:34:40+00:00

URL: https://externals.io/message/69847#69876 · In reply to: #69875

> 
> > […]
>
> 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]

---

## #69877 — Rowan Collins — 2013-10-26T13:14:57+00:00

URL: https://externals.io/message/69847#69877 · In reply to: #69864

> 
> > […]
>
> 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]

---

## #69878 — Joe Watkins — 2013-10-26T14:26:03+00:00

URL: https://externals.io/message/69847#69878 · In reply to: #69875

> 
> > […]
>
> 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...
>
> > […]
>
> 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

---

## #69879 — Rowan Collins — 2013-10-26T15:04:21+00:00

URL: https://externals.io/message/69847#69879 · In reply to: #69878

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

---

Next page: https://externals.io/message/69847.md?page=2
