PHP 7 try - catch: unable to catch “Catchable fatal error”

╄→гoц情女王★ 提交于 2019-12-10 16:19:43

问题


I am playing with try - catch block:

<?php
try {
    $str = "http://rejstrik-firem.kurzy.cz/73631604";
    $domOb = new DOMDocument();
    $html = $domOb->loadHTMLFile($str);
    $domOb->preserveWhiteSpace = false; 
    $container = $domOb->getElementById('ormaininfotab');   
    echo $container; // <========= this is intended error which I want catch
} 
catch (Exception $e) {
   echo "Exception" . $e->getMessage() . ". File: " . $e->getFile() . ", line: " . $e->getLine();
} 

catch (Error $e) {
   echo "Error" . $e->getMessage() . ". File: " . $e->getFile() . ", line: " . $e->getLine();
}
?>

My result is this:

Catchable fatal error: Object of class DOMElement could not be converted to string in /var/www/html/cirkve_ares/test.php on line 8

Why is not this error catched by second catch?


回答1:


As user2782001 mentioned this is not a bug in the eyes of PHP dev's. They even noted that these type of errors should be referenced as 'recoverable':

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.

On the ErrorException manual page there is a neat workaround converting those "catchable/recoverable" errors to ErrorException.

<?php
function exception_error_handler($severity, $message, $file, $line) {
    if (!(error_reporting() & $severity)) {
        // This error code is not included in error_reporting
        return;
    }
    throw new ErrorException($message, 0, $severity, $file, $line);
}
set_error_handler("exception_error_handler");
?>

now you will be able to catch those errors with:

<?php
try {
    // Error code
} catch (Error $e) { // this will catch only Errors 
    echo $e->getMessage();
}
?>

or

try {
    // Error code
} catch (Throwable $t) { // this will catch both Errors and Exceptions
    echo $t->getMessage();
}
?>



回答2:


Someone reported this as a bug to PHP's devs, who promptly decided it was not a bug. https://bugs.php.net/bug.php?id=72948&edit=3

This case has been intentionally omitted ...(in practice you can simply convert the recoverable fatal to an exception using an error handler...)

So you still have to use the

set_error_handler()

function, which we were all hoping to leave behind. PHP's devs are so good at never letting your day be too sunny...




回答3:


There might be some fatal errors which are not even caught by set_error_handler() or \Throwable.

The below implementation will catch the errors which are not even caught by \Throwable as tested in php 7.1. It should only be implemented in your development environment(by just adding it in your development config file) and shouldn't be done in production.

Implementation

register_shutdown_function(function () {
    $err = error_get_last();
    if (! is_null($err)) {
        print 'Error#'.$err['message'].'<br>';
        print 'Line#'.$err['line'].'<br>';
        print 'File#'.$err['file'].'<br>';
    }
});

Example Error

Error# Class Path/To/MyService contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Path/To/MyServiceInterface::add)
Line# 12
File# Path/To/MyService.php


来源:https://stackoverflow.com/questions/41774316/php-7-try-catch-unable-to-catch-catchable-fatal-error

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!