7

In my AWS logs, I have entries like this:

[Wed Feb 06 10:12:22.306730 2019] [php7:error] [pid 28445] [client 172.31.10.7:55646] PHP Fatal error: Uncaught Error: Class 'comet_cache' not found in /var/app/current/project-website-wordpress/wp-content/mu-plugins/comet-cache-ec2-enabler.php:41

Those entries are logged when some certain HTTP 500 request happens.

After checking the code, I have found the following (in Line 41 in the file mentioned):

try {
   comet_cache::clear();
} catch(Exception $e) {
   // if comet cache is not activated, we want to continue anyway
}

This basically makes sense - it seems like the class is not found, but if that were the case, the Exception should be caught in the catch() bloc, and the execution should continue.

Why does PHP crash instead?

1 Answer 1

23

You are not catching because you are tring to catch an \Exception, but what's being thrown it's an \Error.

Considering your error message, I would say you are using PHP >= 7 (you should specificy that, error handling has changed significantly from version 5 to version 7).

On PHP >= 7, most fatal errors are reported not by raising an error, but by throwing an Error object.

So your statement could be rewritten like:

try {
    $a = new ClassNotFindable();
}
catch (\Error $e) {
   // do your catching
}

Furthermore, both Error and Exception classes implement the Throwable interface, so you could catching that directly:

<?php

try {
    $a = new NotFound();
}
catch (\Throwable $t) {
    echo "caught!\n";

    echo $t->getMessage(), " at ", $t->getFile(), ":", $t->getLine(), "\n";
}

You can see it working here.

This is in no way related to AWS, but simply a PHP thing. If you were using PHP < 7 it would still not be caught, but in that case because common errors are not thrown exceptions.

If you were using PHP5, to be able to catch an error as an exception you'd need to set-up a custom error handler. The example in the manual seems quite appropriate:

function exception_error_handler($severidad, $mensaje, $fichero, $línea) {
   if (!(error_reporting() & $severidad)) {
       // Este código de error no está incluido en error_reporting
       return;
   }
   throw new ErrorException($mensaje, 0, $severidad, $fichero, $línea);
}
set_error_handler("exception_error_handler");
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks - this is an important change I seem to only have recognized partly. That means if migrating from PHP 5 to PHP 7 one should check all implementations for places where catch(Exception) should be replaced by catch(Throwable) .
On PHP5 errors were not catchable on try/catch blocks, at least not wihout setting a specific error handler. So the behaviour is completely different, and simply replacing Exception with Throwable will not perform the same function.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.