0

I have a ZF 3 application. Messages I explicitly log with e.g $log->debug() Show up just fine. Exceptions don't. Errors seem to show up because that's the default php config to go to stderr. Here is the relevant lines from modules.config.php:

'service_manager' => [
    'factories' => [
        . . . . 
        'log' => \Zend\Log\LoggerServiceFactory::class,

    ],
],
'log' => [
    'writers' => [
        [
            'name' => 'stream',
            'options' => [ 'stream' => 'php://stderr' ]
        ],
    ],
    'errorHandler' => true,
    'exceptionhandler' => true,
],

The lines in the source that lead me to believe this is the correct config.

    if (isset($options['exceptionhandler']) && $options['exceptionhandler'] === true) {
        static::registerExceptionHandler($this);
    }

    if (isset($options['errorhandler']) && $options['errorhandler'] === true) {
        static::registerErrorHandler($this);
    }

To test it I made the following endpouints:

public function errorAction()
{
    $msg = $this->params()->fromQuery('msg', 'Default Error message');
    trigger_error('Index Error Action' . $msg, E_USER_ERROR);
    $model = new JsonErrorModel(['msg' => $msg]);
    return $model;
}

public function exceptionAction()
{
    $msg = $this->params()->fromQuery('msg', 'Default Error message');
    throw new \RuntimeException('Index Exception Action' . $msg);
    $model = new JsonErrorModel(['msg' => $msg]);
    return $model;
}
Justin Dearing
  • 14,270
  • 22
  • 88
  • 161

1 Answers1

1

You have typo in your configuration array

'log' => [
    ....
    'errorHandler' => true,
    ....
],

This index shouldn't be camelCase it should be errorhandler (all letters are lowercase). I would also add fatal_error_shutdownfunction => true to configutation so you will log fatal errors.

Zend uses set_exception_handler to handle exceptions, so keep in mind that logging exceptions will work only if they are not in try/catch block.

Sets the default exception handler if an exception is not caught within a try/catch block
Source: http://php.net/manual/en/function.set-exception-handler.php

All these functions may be set manually:

\Zend\Log\Logger::registerErrorHandler($logger);
\Zend\Log\Logger::registerFatalErrorShutdownFunction($logger);
\Zend\Log\Logger::registerExceptionHandler($logger);

If you want test it, you can do following things:

Error

public function errorAction()
{
    $log = $this->getServiceLocator()->get('log'); // init logger. You shouldn't use getServiceLocator() in controller. Recommended way is injecting through factory
    array_merge([], 111);
}

It should write in log:

2017-03-09T15:33:47+01:00 WARN (4): array_merge(): Argument #2 is not an array {"errno":2,"file":"[...]\\module\\Application\\src\\Application\\Controller\\IndexController.php","line":80}  

Fatal error

public function fatalErrorAction()
{
    $log = $this->getServiceLocator()->get('log'); // init logger. You shouldn't use getServiceLocator() in controller. Recommended way is injecting through factory
    $class = new ClassWhichDoesNotExist();
}

Log:

2017-03-09T15:43:06+01:00 ERR (3): Class 'Application\Controller\ClassWhichDoesNotExist' not found {"file":"[...]\\module\\Application\\src\\Application\\Controller\\IndexController.php","line":85}

Or you could initialize logger in Module.php file if you need logger globally.

I don't think it is possible to log exception in controller's action. I'm not sure, but action is dispatched in try/catch block.

SzymonM
  • 904
  • 8
  • 14
  • I fixed that, and added the fatal error logging. I still don't see thme in the logs. I edited the question with my sample endpoints that are not working. The exceptions are unhandled. – Justin Dearing Mar 09 '17 at 14:12
  • I edited my answer.. You just didn't initialize logger. In configuration file you register service/model, but Zend create class from it after first call for this service. – SzymonM Mar 09 '17 at 14:59
  • Thanks. That did it! – Justin Dearing Mar 11 '17 at 00:22