We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Can't catch php memory exhausted error with Phalcon's beforeException

My beforeException function looks like this (simplified):

public function beforeException(Event $event, Dispatcher $dispatcher, \Exception $exception) {
  ...
  $this -> _logger -> log(get_class($exception) . '===========================================' . 
   PHP_EOL . $exception -> getMessage() . PHP_EOL, Logger::ERROR);
   if (!$isXdebugEnabled){
             $this -> flashSession->error('Unexpected error occured. Please contact the administrator.');
             $this -> response -> redirect($moduleName . '/index/route500');
             return false;    
    }
}

and intended to supress error messages on production by logging them and redirect client to page 500. Most of the time it works but it fails when encontering errors like this:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes)

Is it possible to catch this type of error in principle?



79.0k
Accepted
answer
edited Nov '16

As you see, that is PHP fatal error, thus it cannot be catched by any exception handler. For catching those lower-level errors (synax, fatal etc) you'd need to use native PHP function:

//Define shutdown function to handle fatal and all other native PHP errors (non-exceptions)
register_shutdown_function(function () use ($config) {
    //include error handler class
    if (!class_exists(__NAMESPACE__ . '\\' . 'ErrorHandler')) require APP_PATH . $config->application->controllersDir . $config->application->errorHandlerClassless;

    //define error buffer
    $d = ', '; $errmsg = ''; $lasterr = error_get_last() ? error_get_last() : null;

    //validate
    if (!count($lasterr)) return;

    //prepare error buffer
    foreach ($lasterr as $k => $v) $errmsg .= $k . ': ' . $v . $d;

    //Process error via handler class
    ErrorHandler::stopMiddleware(500, rtrim($errmsg, $d), 0xff);
});

This is my custom error handler class. It will set HTTP status, and format response buffer. The most important part is error_get_last(), and you can prepare response or a log file however you want.