php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #72089 handle all fatal errors with try catch
Submitted: 2016-04-23 21:28 UTC Modified: 2016-06-17 09:41 UTC
Votes:8
Avg. Score:4.4 ± 0.9
Reproduced:7 of 7 (100.0%)
Same Version:3 (42.9%)
Same OS:5 (71.4%)
From: paulobitfranca at gmail dot com Assigned:
Status: Re-Opened Package: *General Issues
PHP Version: 7.0.5 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: paulobitfranca at gmail dot com
New email:
PHP Version: OS:

 

 [2016-04-23 21:28 UTC] paulobitfranca at gmail dot com
Description:
------------
I mind that some fatal errors are not handled by the try/catch yet.
For example, when I use require() and the include file doesn't exist.

Is it possible that in a future version, all the fatal erros can be handled by try/catch?

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

	error_reporting(E_ALL);

	try
	{
    	require("xxx.php");

	}
	catch (Throwable $e)
	{
    	echo "An error: file doesn't exist"
	}

        echo "hi!";


Expected result:
----------------
An error: file doesn't exist
Hi!

Actual result:
--------------
Fatal error: require() [function.require.html: Failed opening required 'xxx.php' (include_path='.:/opt/php7/includes') in /var/www/html/teste.php on line 8

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-04-26 17:50 UTC] cmb@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: cmb
 [2016-04-26 17:50 UTC] cmb@php.net
Generally, that has already been done for PHP 7.0.0 where
reasonable and possible, see
<https://wiki.php.net/rfc/engine_exceptions_for_php7>.

With regard to your example: if a file is *required* and it can't
be included, it doesn't make much sense to go on. If on the other
hand the file is not really required, just `include` it.
 [2016-06-17 07:57 UTC] lisachenko dot it at gmail dot com
I think, that we should replace all possible places with Fatal Errors with correct throwing of Error. 

This will give us more control over the file loading process and make it more atomic, because additional checks if(file_exists($file) && is_readable($file)) generate extra stat commands and slow. Moreover, for highload project, we can hit a situation where if succeeded, but require will fail because file was deleted after check.

Code like this:
try {
    require $fileName;
} catch (Error $e) {
    echo "Oops, " . $e;
}

is much more reliable than this one:

if (file_exists($fileName) && is_readable($fileName)) {
    @include $fileName; // Silencing errors for the case of race-condition, etc
}
 [2016-06-17 09:41 UTC] cmb@php.net
-Status: Closed +Status: Re-Opened -Assigned To: cmb +Assigned To:
 [2017-06-07 09:05 UTC] mplomer at gmx dot de
> "if a file is *required* and it can't be included, it doesn't make much sense to go on."

You can say the same for a ParseError ;-)

I am currently designing a simple router where it is possible that a PHP file does not exist (to avoid a central configuration), and I want to throw a 404 then. I was happy to handle this with the new PHP 7 exception concept, as this was my first use case for it ... but then I also noticed, it just does not work for non-existent files :-(

IMHO it is really inconsistent to throw errors for parse-errors but then generate fatal errors for non-existent files.
 [2017-06-07 09:08 UTC] spam2 at rhsoft dot net
the point is with PHP7 should *anything* which is not catchable considered and handeled as bug
 [2017-06-07 09:12 UTC] spam2 at rhsoft dot net
> With regard to your example: if a file is *required* and it can't
> be included, it doesn't make much sense to go on

sorry but that is nonsense - it makes *a lot* of sense to go on with a custom error-page with some useful hint instead a blank page and when it comes to modules of your application and somewhere deep there is a require() you can't do much and by the fact that is is not catchable IT BREAKS ANY EXISTING ERROR-HANDLER and you can not do anything about it while a *parse error* in some of the includes CAN be catched - typical php inconsistency for no sane reason
 [2017-07-27 20:36 UTC] php at pointpro dot nl
In the same train of thought, why does it make sense that running foo.php, with these contents:

---------- foo.php
<?php
include "bar.php";
----------

and

---------- bar.php
<?php
asdfkoaw jeokjwe foijsdfklojsefwe
----------


Would throw a 'ParseError' exception that can be caught and handled, but when I replace the content of bar.php with the much more correct code:

---------- bar.php
<?php

class A implements B
{}
----------

Gives me a unrecoverable fatal error: Interface 'B' not found.

So a very big +1000 on making all failures in requiring files, and basically ALL errors, throw exceptions that can be caught.

Even if the script can't continue, it can do its best to provide a meaningful or at least thoughtful error message to the client.
 [2017-07-27 20:40 UTC] php at pointpro dot nl
By the way, this is issue is linked to PHP 7.0.5, but it also applies to 7.0.21, 7.1.7 and 7.2.0beta1.
 [2017-07-27 21:28 UTC] spam2 at rhsoft dot net
it's a general issue - with having √úeverything* as exception you can esily write code which handles 99.9% of all cases in a very cheap try{] while handle servers missing something in the catch part - unhandeled you get the same result as now but *you can* handle it properly
 [2017-11-28 20:48 UTC] ryan dot jentzsch at gmail dot com
As an actual case where this issue is a valid concern. Pseudocode that illustrates the issue:

<?php
try {
    SoapClient::__constructor($wsdl)
} catch (\Throwable $t) {
    // Never executed because ANYTIME the constructor can not PARSE the WSDL a script exiting fatal is thrown and not caught!
    // The SOAP implementation in PHP offers ZERO fault tolerance. 
    // We can't degrade gracefully. 
    // All processing stops and the script is exited!
    // Why in the name of sanity is a SOAP PARSE issue NOT throwing a SOAPFault and instead we get a fatal error?
}
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Fri Sep 20 09:01:26 2019 UTC