Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

errcontext optional #167

Merged
merged 2 commits into from
Sep 9, 2021
Merged

errcontext optional #167

merged 2 commits into from
Sep 9, 2021

Conversation

Dringho
Copy link

@Dringho Dringho commented Sep 7, 2021

I triggered this bug doing
filesize('/tmp/file_does_not_exist')

Too few arguments to function Zend_Log::errorHandler(), 4 passed and exactly 5 expected
#0 [internal function]: Zend_Log->errorHandler()

I have no idea the root cause on why there is no context, I'm running PHP 8.0.10. Adding = null to errcontext it's a harmless quick fix.

I triggered this bug doing 
`filesize('/tmp/file_does_not_exist')`

```
Too few arguments to function Zend_Log::errorHandler(), 4 passed and exactly 5 expected
#0 [internal function]: Zend_Log->errorHandler()
```

I have no idea the root cause on why there is no context, I'm running PHP 8.0.10. Adding = null to errcontext it's a harmless quick fix.
@Shardj
Copy link
Owner

Shardj commented Sep 9, 2021

Context should default to an empty array if anything, to be psr-3 compliant.

I use this by the way, if you want a psr-3 compliant \Zend_log it might help:

<?php
namespace Core;

use Psr\Log\LoggerInterface;

class Log extends \Zend_Log implements LoggerInterface {

    /**
     * Override handling of php errors to include stack trace and line numbers in message.
     *
     * @param int $errno
     * @param string $errstr
     * @param string $errfile
     * @param int $errline
     * @param array $errcontext
     * @return boolean
     */
    public function errorHandler($errno, $errstr, $errfile, $errline, $errcontext = []) { // @codingStandardsIgnoreLine
        $backtrace = $this->generateBacktrace();
        $errstr .= ' in ' . $errfile
                    . ' on line ' . $errline
                    . "\nStack trace: \n" . $this->generateBacktraceAsString($backtrace);

        $errorLevel = error_reporting();
        if ($errorLevel & $errno) {
            if (isset($this->_errorHandlerMap[$errno])) {
                $priority = $this->_errorHandlerMap[$errno];
            } else {
                $priority = Zend_Log::NOTICE;
            }
            $this->log(
                $errstr,
                $priority,
                [
                    'errno' => $errno,
                    'file' => $errfile,
                    'line' => $errline,
                    'context' => $errcontext,
                    'trace' => $backtrace
                ]
            );
        }
        return false;
    }

    /**
     * Generate a backtrace for a PHP error if one isn't provided and then convert it to a string
     *
     * @param string[]|null
     * @return string
     */
    protected function generateBacktraceAsString(?array $backtrace = null): string {
        foreach ($backtrace ?? $this->generateBacktrace() as $i => $node) {
            $lines[] = '#' . $i . ' '
                    . (isset($node['file']) ? $node['file'] : '<unknown file>') . ' '
                    . (isset($node['line']) ? '(' . $node['line'] . ')' : '<unknown line>')
                    . ': '
                    . (isset($node['class']) ? $node['class'] . '->' : '')
                    . $node['function'] . "()";
        }
        return implode("\n", $lines);
    }

    /**
     * Generate a backtrace for a PHP error
     *
     * @return mixed[][]
     */
    protected function generateBacktrace(): array {
        // discard stack items within error routine
        $trace = debug_backtrace();
        foreach ($trace as $index => $call) {
            if ($call['function'] === 'errorHandler' && isset($call['class']) && $call['class'] === 'Pi\Core\Log') {
                $trace = array_slice($trace, $index + 1);
                break;
            }
        }
        return $trace;
    }

    public function critical($message, array $context = []) {
        $this->crit($message, $context);
    }

    public function emergency($message, array $context = []) {
        $this->emerg($message, $context);
    }

    public function error($message, array $context = []) {
        $this->err($message, $context);
    }

    public function warning($message, array $context = []) {
        $this->warn($message, $context);
    }

    public function alert($message, array $context = []) {
        parent::alert($message, $context);
    }

    public function notice($message, array $context = []) {
        parent::notice($message, $context);
    }

    public function info($message, array $context = []) {
        parent::info($message, $context);
    }

    public function debug($message, array $context = []) {
        parent::debug($message, $context);
    }
}

@Dringho
Copy link
Author

Dringho commented Sep 9, 2021

Fixed, added empty array as default.

@Shardj Shardj merged commit 9eb9746 into Shardj:master Sep 9, 2021
@glensc
Copy link
Collaborator

glensc commented Sep 10, 2021

x-ref (applied):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants