• Thanks for your work on Query Monitor. It looks to be a very helpful tool and a quicker way to get at issues than manually enabling and reading the debug log, especially for less experienced users.

    In my own plugin I’m using the error suppression operator to create a directory if it does not exist yet, and to read a file without first checking whether it exists, because this is the only way I know to perform these operations without a race condition.

    It seems that on PHP 8, Query Monitor reports suppressed errors without marking them as such. I haven’t tested it myself, but received a report about it and have had a look at the source code of Query Monitor.

    Here’s what I found and a suggested change, if you think this might improve the plugin.

    In collectors/php_errors.php on line 227, we find:

        if ( 0 === error_reporting() && 0 !== $this->error_reporting ) {
            // This is most likely an @-suppressed error
            $error_group = 'suppressed';
        }

    This code is meant to detect errors that have been suppressed using the @ operator.

    However, since PHP 8 error_reporting() no longer returns 0 when the suppression operator is used. Instead it returns the value E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE. These are all usually fatal errors.

    See: https://www.php.net/manual/en/language.operators.errorcontrol.php and https://www.php.net/manual/en/errorfunc.constants.php

    I suggest checking the error_reporting() value as follows:

    private const UNSUPPRESSABLE_ERRORS = E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE;
        if ( 0 === ( error_reporting() & ~self::UNSUPPRESSABLE_ERRORS ) && 0 !== $this->error_reporting ) {
            // This is most likely an @-suppressed error
            $error_group = 'suppressed';
        }

    This should check that error_reporting() contains only these unsuppressable errors (or fewer), and should work for PHP 7 as well as PHP 8.

    This should be fine as well:

        $error_reporting = error_reporting();
        if ( ( 0 === $error_reporting() || self::UNSUPPRESSABLE_ERRORS === $error_reporting() ) && $error_reporting() !== $this->error_reporting ) {
            // This is most likely an @-suppressed error
            $error_group = 'suppressed';
        }

    I hope this will be helpful to you.

Viewing 2 replies - 1 through 2 (of 2 total)
Viewing 2 replies - 1 through 2 (of 2 total)
  • The topic ‘Handle suppressed errors on PHP 8’ is closed to new replies.