php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #70050 set_exception_handler receives non-exception objects
Submitted: 2015-07-12 10:11 UTC Modified: 2016-01-11 15:42 UTC
From: mfischer@php.net Assigned: bishop (profile)
Status: Closed Package: *General Issues
PHP Version: 7.0.0beta1 OS: Ubuntu 14.04.2 LTS
Private report: No CVE-ID: None
 [2015-07-12 10:11 UTC] mfischer@php.net
Description:
------------
A callable set with "set_exception_handler" receives objects which are not of type Exception.

Why is the "Exception" in the example script typehinted?

Why not, the documentation states:
"This handler function needs to accept one parameter, which will be the exception object that was thrown."

Which is not true anymore.

I welcome "Fatal error" being turned into something which is handleable, but this seems like a BC break and IMHO everything which is thrown should be of type \Exception .

Test script:
---------------
<?php
set_exception_handler(
  function (Exception $e) {
    var_dump('yodo');
  }
);
Foo::bar;


Expected result:
----------------
The handler should receive something which is an "Exception", not an "Error" object.

Actual result:
--------------
$ php test.php

Fatal error: Uncaught TypeError: Argument 1 passed to {closure}() must be an instance of Exception, instance of Error given in /vagrant/api.swat.io/test.php:3
Stack trace:
#0 [internal function]: {closure}(Object(Error))
#1 {main}
  thrown in /vagrant/api.swat.io/test.php on line 3

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-07-12 10:20 UTC] requinix@php.net
-Type: Bug +Type: Documentation Problem
 [2015-07-12 10:20 UTC] requinix@php.net
So what you're saying is that we need to make sure all of that documentation gets updated to reflect the new Throwable stuff, right?

>everything which is thrown should be of type \Exception
But... you already know this won't be the case: you voted in favor of the engine exceptions RFC. Which clearly said that there will be a hierarchy of exceptions above Exception. And there was all the discussion about this on the internals list.
 [2015-07-12 11:03 UTC] mfischer@php.net
> So what you're saying is that we need to make sure all of that documentation gets updated to reflect the new Throwable stuff, right?

No, I'm saying there's a BC problem.

>> everything which is thrown should be of type \Exception
> But... you already know this won't be the case: you voted in favor of the engine exceptions RFC.

I don't see the relevancy here. But since you insist on this point: I voted against introducing a BaseException.

TBH I forgot about this RFC and how I voted and was kind of independently hit by this issue, which to no-surprise matches how I voted and validates my past choice.

thanks,
- Markus
 [2015-07-13 07:15 UTC] laruence@php.net
Actually, I am kindof understand this problem. and maybe we should do some improvements.

that is, if the exception be throw is not an compatible exception type of exception_handler.

then the exception handler should not be called.

actually, this problem is also exists in php5, like

<?php
set_exception_handler(
    function (ExceptionA $e) {
        var_dump('yodo');
    }
);

class exceptionA extends exception{};
throw new Exception("xxx");
 [2015-07-13 07:19 UTC] laruence@php.net
-Status: Open +Status: Analyzed
 [2015-07-13 20:31 UTC] ab@php.net
As for me - what is bad is the name set_exception_handler which now catches Trowable indeed. But IMHO - not invoking it only because of name is not handy. Then users have no catch all solution. Given a similar issue exists in php5, IMHO it is a topic of documentation. It is too late to change names or introducing a better solution in 7.0 :(

Thanks.
 [2015-07-14 00:21 UTC] trowski@php.net
I think this issue is best addressed by clear documentation that upgrading to PHP 7 will require the type declaration on exception handlers to be changed from Exception to Throwable. It should be noted that an Error object and any future implementor of Throwable are still exceptions, they just aren't instances of Exception. :) I apologize for the documentation nightmare, but this isn't without precedence in other languages such as Python and Java.
 [2015-08-26 17:48 UTC] jhdxr@php.net
We have already mentioned this issue as one of the backward incompatible changes in migration part, but in the doc of set_exception_handler, the handler's signature is still 
> void handler ( Exception $ex )
and the note below only says we should not provide an explicit Exception type hint in php 7 , without any words about Throwable. I think we may list two different signature (php 5.*, php 7), or make the note more clear.
 [2016-01-11 15:42 UTC] bishop@php.net
-Status: Analyzed +Status: Closed -Assigned To: +Assigned To: bishop
 [2016-01-11 15:42 UTC] bishop@php.net
Fixed in current documentation:

-----

exception_handler
Name of the function to be called when an uncaught exception occurs. This handler function needs to accept one parameter, which will be the exception object that was thrown. This is the handler signature before PHP 7:
void handler ( Exception $ex )

Since PHP 7, most errors are reported by throwing Error exceptions, which will be caught by the handler as well. Both Error and Exception implements the Throwable interface. This is the handler signature since PHP 7:
void handler ( Throwable $ex )

NULL may be passed instead, to reset this handler to its default state.

Caution
Note that providing an explicit Exception type hint for the ex parameter in your callback will cause issues with the changed exception hierarchy in PHP 7.

-----

http://php.net/manual/en/function.set-exception-handler.php
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 06:01:30 2024 UTC