# E_RECOVERABLE_ERROR for "Call to a member function on a non-object"

- Thread: https://externals.io/message/66716
- Original archive: https://news-web.php.net/php.internals/66716
- Started by Richard Bradley on 2013-03-20T14:37:51+00:00
- Messages: 6
- 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

---

## #66716 — Richard Bradley — 2013-03-20T14:37:51+00:00

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

I'd like to patch PHP to make "Call to a member function on a non-object" an `E_RECOVERABLE_ERROR` instead of an E_ERROR.

I have not been able to find any previous discussion of making this change, but there are several PHP bugs requesting it:
*         #51882<https://bugs.php.net/bug.php?id=51882> Call To Member Function on Non-Object Should Throw An Exception
*         #46601<https://bugs.php.net/bug.php?id=46601> `E_RECOVERABLE_ERROR` for "Call to a member function on a non-object"
*         #51848<https://bugs.php.net/bug.php?id=51848> Non-object method call errors should be catchable with `set_error_handler()`
*         #63538<https://bugs.php.net/bug.php?id=63538> "Call to undefined function" should be catchable

I have read https://blogs.oracle.com/opal/entry/the_mysterious_php_rfc_process

I would like to know:

1.       Do I need to create an RFC for this change, or could I just create a pull request in GitHub?

2.       Would anyone object to this change? For example on backwards-compatibility grounds?

3.       If I put the effort in to create the RFC and a patch, would it be likely to be accepted?

4.       Has anyone attempted this change before and had it rejected, or given up?

Technical summary:

If you make a member function call on a null value (or any other non-object), a fatal error is raised. This makes it completely impossible to recover from null-ref errors.
For example, in a Behat test suite, you might write:
                $session->getPage()->find('css', '#next')->click()

If the "find" function returns NULL, then the "->click()" call is fatal. Your test suite will not be able to continue at the next test, and all further output will be lost.

The simple workaround is to check the value before invoking a function, i.e.:
                $button = $session->getPage()->find('css', '#next');
                if (empty($button)) {
                                throw new Exception("Could not find #next button");
                }
                $button->click()

However, this is laborious and easy to overlook. The consequences of forgetting this manual null check seem disproportionately and unnecessarily severe.

It would be more convenient if the null dereference was an E_RECOVERABLE_ERROR, which would allow scripts to convert the error into an exception, and continue the script at the next suitable point, via a "catch".

The documentation for `E_ERROR` at http://php.net/manual/en/errorfunc.constants.php says that these errors are "Fatal run-time errors. These indicate errors that can not be recovered from, such as a memory allocation problem. Execution of the script is halted."

It doesn't seem to me that dereferencing "null" with "->" would be an error that "can not be recovered from, such as a memory allocation problem". In fact, the interpreter should be in a very predictable state, and quite capable of continuing if the user's script requests it.
This error is a much better match for the description of `E_RECOVERABLE_ERROR` from the same page: "a probably dangerous error occurred, but did not leave the Engine in an unstable state"

See also http://stackoverflow.com/questions/15502559/php-turn-call-to-a-member-function-on-a-non-object-into-exception

Thanks for your time,


Rich




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

softw i re
Sunday Times Best Small Companies 2012 - 6th in the UK
Web : www.softwire.com<http://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

---

## #66717 — Ferenc Kovacs — 2013-03-20T16:14:03+00:00

URL: https://externals.io/message/66716#66717 · In reply to: #66716

On Wed, Mar 20, 2013 at 3:37 PM, Richard Bradley <
Richard.Bradley@softwire.com> wrote:

> I'd like to patch PHP to make "Call to a member function on a non-object"
> an `E_RECOVERABLE_ERROR` instead of an E_ERROR.
>
> I have not been able to find any previous discussion of making this
> change, but there are several PHP bugs requesting it:
> *         #51882<https://bugs.php.net/bug.php?id=51882> Call To Member
> Function on Non-Object Should Throw An Exception
> *         #46601<https://bugs.php.net/bug.php?id=46601>
> `E_RECOVERABLE_ERROR` for "Call to a member function on a non-object"
> *         #51848<https://bugs.php.net/bug.php?id=51848> Non-object method
> call errors should be catchable with `set_error_handler()`
> *         #63538<https://bugs.php.net/bug.php?id=63538> "Call to
> undefined function" should be catchable
>
> I have read
> https://blogs.oracle.com/opal/entry/the_mysterious_php_rfc_process
>
> I would like to know:
>
> 1.       Do I need to create an RFC for this change, or could I just
> create a pull request in GitHub?
>
> 2.       Would anyone object to this change? For example on
> backwards-compatibility grounds?
>
> 3.       If I put the effort in to create the RFC and a patch, would it be
> likely to be accepted?
>
> 4.       Has anyone attempted this change before and had it rejected, or
> given up?
>
> Technical summary:
>
> If you make a member function call on a null value (or any other
> non-object), a fatal error is raised. This makes it completely impossible
> to recover from null-ref errors.
> For example, in a Behat test suite, you might write:
>                 $session->getPage()->find('css', '#next')->click()
>
> If the "find" function returns NULL, then the "->click()" call is fatal.
> Your test suite will not be able to continue at the next test, and all
> further output will be lost.
>
> The simple workaround is to check the value before invoking a function,
> i.e.:
>                 $button = $session->getPage()->find('css', '#next');
>                 if (empty($button)) {
>                                 throw new Exception("Could not find #next
> button");
>                 }
>                 $button->click()
>
> However, this is laborious and easy to overlook. The consequences of
> forgetting this manual null check seem disproportionately and unnecessarily
> severe.
>
> It would be more convenient if the null dereference was an
> E_RECOVERABLE_ERROR, which would allow scripts to convert the error into an
> exception, and continue the script at the next suitable point, via a
> "catch".
>
> The documentation for `E_ERROR` at
> http://php.net/manual/en/errorfunc.constants.php says that these errors
> are "Fatal run-time errors. These indicate errors that can not be recovered
> from, such as a memory allocation problem. Execution of the script is
> halted."
>
> It doesn't seem to me that dereferencing "null" with "->" would be an
> error that "can not be recovered from, such as a memory allocation
> problem". In fact, the interpreter should be in a very predictable state,
> and quite capable of continuing if the user's script requests it.
> This error is a much better match for the description of
> `E_RECOVERABLE_ERROR` from the same page: "a probably dangerous error
> occurred, but did not leave the Engine in an unstable state"
>
> See also
> http://stackoverflow.com/questions/15502559/php-turn-call-to-a-member-function-on-a-non-object-into-exception
>
> Thanks for your time,
>
>
> Rich
>
>
>
>
> Richard Bradley
> Tel : 020 7485 7500 ext 3230 | Fax : 020 7485 7575
>
> softw i re
> Sunday Times Best Small Companies 2012 - 6th in the UK
> Web : www.softwire.com<http://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
>

1, yes
2, yes
3, depends on the patch
4, yes, at least there were a couple of discussions in general about
removing/converting some of the fatals to recoverable fatas

In general there are cases where the cause of the error isn't a fatal one,
but it would leave the engine in a half-baked state and usually it is
easier to fatal out than implement a proper state recover/reset so that the
whole thing won't blow up to your face at the next execution step.

ps: there were also https://bugs.php.net/bug.php?id=54195&edit=2

-- 
Ferenc Kovács
@Tyr43l - http://tyrael.hu

---

## #66718 — Ferenc Kovacs — 2013-03-20T16:18:41+00:00

URL: https://externals.io/message/66716#66718 · In reply to: #66717

>
>
>
> On Wed, Mar 20, 2013 at 3:37 PM, Richard Bradley <
> Richard.Bradley@softwire.com> wrote:
>
> > […]
>
> 1, yes
> 2, yes
> 3, depends on the patch
> 4, yes, at least there were a couple of discussions in general about
> removing/converting some of the fatals to recoverable fatas
>
> In general there are cases where the cause of the error isn't a fatal one,
> but it would leave the engine in a half-baked state and usually it is
> easier to fatal out than implement a proper state recover/reset so that the
> whole thing won't blow up to your face at the next execution step.
>
> ps: there were also https://bugs.php.net/bug.php?id=54195&edit=2
>
>
btw. there is discussion going on about this generic problem currently:
http://news.php.net/php.cvs/71635
http://www.mail-archive.com/internals@lists.php.net/msg64708.html

-- 
Ferenc Kovács
@Tyr43l - http://tyrael.hu

---

## #66719 — Richard Bradley — 2013-03-20T16:29:28+00:00

URL: https://externals.io/message/66716#66719 · In reply to: #66717

> > […]
>
> > […]
> 1, yes

OK, will do

> > […]
> 2, yes

Could you be more specific?
I was hoping to head off some of the objections in this email thread, or at least to avoid coding up a patch if it is certain to be rejected.
Could you elaborate on what the objections might be, and what measures I could put in place to overcome them?

> > […]
> 3, depends on the patch

Of course. Could you be more specific? Are there any particular issues the patch would need to address to be accepted? Anyone in particular I need to convince to get this merged in? Or should I just do my best and trust in the RFC voting system?

> > […]
> 4, yes, at least there were a couple of discussions in general about removing/converting some of the fatals to recoverable fatals

Thanks: do you have any pointers for where I can find this?
I get no relevant hits on wiki.php.net or on the "internals" list search at marc.info for search terms like "E_RECOVERABLE_ERROR" or "Call to a member function on a non-object".

> ps: there were also https://bugs.php.net/bug.php?id=54195&edit=2

Thanks; I'll add this to the list of relevant bugs. I'll update all the bugs if / when the RFC gets resolved.

Best,


Rich



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

softwire
Sunday Times Best Small Companies 2012 - 6th in the UK
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

---

## #66720 — Ferenc Kovacs — 2013-03-20T16:49:22+00:00

URL: https://externals.io/message/66716#66720 · In reply to: #66719

> > […]
> backwards-compatibility grounds?
> > […]
>
> Could you be more specific?
> I was hoping to head off some of the objections in this email thread, or
> at least to avoid coding up a patch if it is certain to be rejected.
> Could you elaborate on what the objections might be, and what measures I
> could put in place to overcome them?
>

I can't talk for the others, but my experience on the list tells me that
this isn't an easy problem, otherwise it would be solved already, and some
of the voters are conservative when comes to changing the status quo, so
personally I would be surprised if nobody would object such a change, but
this shouldn't hold you back, the important thing is to have the majority
of the votes, you can't satisfy everybody.
your best bet is to have a clear and unbiased RFC and a nice patch.


>
> > […]
> it be likely to be accepted?
> > […]
>
> Of course. Could you be more specific? Are there any particular issues the
> patch would need to address to be accepted? Anyone in particular I need to
> convince to get this merged in? Or should I just do my best and trust in
> the RFC voting system?
>

the latter.


>
> > […]
> or given up?
> > […]
> removing/converting some of the fatals to recoverable fatals
>
> Thanks: do you have any pointers for where I can find this?
> I get no relevant hits on wiki.php.net or on the "internals" list search
> at marc.info for search terms like "E_RECOVERABLE_ERROR" or "Call to a
> member function on a non-object".
>

there were some good discussion in the
http://grokbase.com/t/php/php-internals/128335vjrj/error-handling-brainstormingthread
(see for example the reply from Nikita where he also mentioned the
cases when the fatal isn't really a fatal, just hard to recover from
sanely).
some other related discussion happened in
http://www.mail-archive.com/internals@lists.php.net/msg60652.html
and the closest thread that I can found would be
http://grokbase.com/t/php/php-internals/122nywvc5f/exceptions-for-method-on-non-object-rather-than-fatal-desired-feature

---

## #66721 — Richard Bradley — 2013-03-20T17:14:45+00:00

URL: https://externals.io/message/66716#66721 · In reply to: #66720

> > […]
>
> there were some good discussion in the http://grokbase.com/t/php/php-internals/128335vjrj/error-handling-brainstorming thread
> (see for example the reply from Nikita where he also mentioned the cases when the fatal isn't really a fatal, just hard to recover from sanely).
> some other related discussion happened in http://www.mail-archive.com/internals@lists.php.net/msg60652.html

Thanks, that’s very helpful.

> and the closest thread that I can found would be
> http://grokbase.com/t/php/php-internals/122nywvc5f/exceptions-for-method-on-non-object-rather-than-fatal-desired-feature

That seems to be the exact same proposal, which is encouraging in some ways, but discouraging in others  :-)
The thread was quickly derailed with discussion of turning errors into exceptions; which I don't think is needed here. We just need to change the category of this error (and ensure that the interpreter is in a suitable state to recover from the error, if the user chooses to do so).

I have emailed Ralf Lang to see how far he got after that thread.

> see for example the reply from Nikita

That message seemed to be related to converting errors to exceptions.
I don't propose to do that; I just hope to convert some E_ERRORs to `E_RECOVERABLE_ERROR` 

> there were some good discussion in the http://grokbase.com/t/php/php-internals/128335vjrj/error-handling-brainstorming thread

I have emailed Derick Rethans about this comment:
http://grokbase.com/t/php/php-internals/128335vjrj/error-handling-brainstorming#201208272kxvjtb16cvqpd4n8aeweqtwk8
where he suggested there was a specific reason that the remaining E_ERRORs could not be converted to E_RECOVERABLE_ERRORs.

I'll copy any replies to the list.

Best,


Rich




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

softwire
Sunday Times Best Small Companies 2012 - 6th in the UK
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
