johnbillion / query-monitor

The developer tools panel for WordPress
https://querymonitor.com
GNU General Public License v2.0
1.59k stars 208 forks source link

error supression is not detected correctly on PHP8+ #808

Open calvinalkan opened 1 year ago

calvinalkan commented 1 year ago

This condition will never return true,

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

On PHP8+, error_reporting never return 0.

Warning

Prior to PHP 8.0.0, the error_reporting() called inside the custom error handler always returned 0 if the error was suppressed by the @ operator. As of PHP 8.0.0, it returns the value E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE.

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

This causes suppressed errors to be reported as actual errors.

Instead, something like this should be used:

    private function nonSilentErrorTypes(): int
    {
        return E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR | E_PARSE;
    }

    private function isErrorSuppressed(): bool
    {
        $current_level = error_reporting();

        if (PHP_MAJOR_VERSION > 7) {
            // https://www.php.net/manual/en/language.operators.errorcontrol.php
            return $current_level === $this->nonSilentErrorTypes();
        }

        return 0 === $current_level;
    }
johnbillion commented 1 year ago

Thanks, this was reported in the support forums too. See #801. I'll close that one off as this ticket has more info.