php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72948 Uncatchable "Catchable" fatal error for class to string conversions
Submitted: 2016-08-26 13:44 UTC Modified: 2021-12-31 16:09 UTC
From: fredrik at neam dot se Assigned: nikic (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 7.1.0beta3 OS:
Private report: No CVE-ID: None
 [2016-08-26 13:44 UTC] fredrik at neam dot se
Description:
------------
When attempting to convert a class to a string, the resulting "Catchable" fatal error is not being caught.

This results in confusion regarding whether or not PHP7's new ability to catch these fatal errors work or not. It turns out that some catchable fatal errors indeed can be caught, while some don't, like the one being reported here. 

This has been confirmed using the below test script against all active php and hhvm versions: 
https://3v4l.org/GeNpF

Test script:
---------------
<?php

echo "PHP Version: " . PHP_VERSION . "\n";

try {

    $v = new DateTime();
    $v = (string) $v;

} catch (Error $e) {

    echo "Caught 'Catchable fatal error' with message: " . $e->getMessage();
    die();

}

echo "Did not catch 'Catchable fatal error'";


Expected result:
----------------
The Catchable fatal error should be caught

Actual result:
--------------
The Catchable fatal error is acting like a non-catchable fatal error

Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-08-26 13:48 UTC] fredrik at neam dot se
-Operating System: linux +Operating System:
 [2016-08-26 13:48 UTC] fredrik at neam dot se
Removed operating system value since this is likely not OS-specific
 [2016-08-26 17:28 UTC] cmb@php.net
-Package: *Programming Data Structures +Package: Scripting Engine problem -Assigned To: +Assigned To: nikic
 [2016-08-26 17:28 UTC] cmb@php.net
> This results in confusion regarding whether or not PHP7's new
> ability to catch these fatal errors work or not.

The issue is not the catching of the exception, but rather that in
this case no exception is thrown at all; instead a classic
E_RECOVERABLE error is raised; otherwise you'd see a stack trace.

@nikic Has this case[1] been deliberately omitted, or has it just
been overlooked?

[1] <https://github.com/php/php-src/blob/PHP-7.1.0beta3/Zend/zend_operators.c#L889>
 [2016-08-26 18:46 UTC] nikic@php.net
This case has been intentionally omitted, because throwing exceptions from string conversions is ostensibly unsafe (in practice you can simply convert the recoverable fatal to an exception using an error handler, so it's sort of a moot argument).

Btw, we should get rid of any references to "catchable" fatal errors (if they still exist) in favor of "recoverable" fatal errors. Using "catchable" here is confusing as they cannot be caught using catch blocks.
 [2016-09-06 12:16 UTC] cmb@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=727b422ad91f0d767d8f0fb3951b89fa9da8668f
Log: Fix #72948: Uncatchable &quot;Catchable&quot; fatal error for class to string conversions
 [2016-09-06 12:16 UTC] cmb@php.net
-Status: Assigned +Status: Closed
 [2016-10-17 10:08 UTC] bwoebi@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=727b422ad91f0d767d8f0fb3951b89fa9da8668f
Log: Fix #72948: Uncatchable &quot;Catchable&quot; fatal error for class to string conversions
 [2021-12-31 15:49 UTC] cryptomister99 at gmail dot com
Since PHP 7.4 this has changed, so now it throws an exception that is catched in the (try) catch block, and not catched in the user error handler (using set_error_handler).
Is there an updated documentation about all of this? I've seen other odd cases, and I've noticed that since PHP 7.4 there have been important changes related to react for "fatal errors".
 [2021-12-31 16:09 UTC] requinix@php.net
@cryptomister99: This is documented in the 7.4 migration guide.

https://www.php.net/manual/en/migration74.new-features.php
> Allow exceptions from __toString()
> Throwing exceptions from __toString() is now permitted. Previously this resulted
> in a fatal error. Existing recoverable fatal errors in string conversions have
> been converted to Error exceptions.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 15:01:30 2024 UTC