Buona domanda. Penso che questo sia un problema generale con E_RECOVERABLE_ERROR
PHP.
Quello che hai nella tua domanda è il gestore delle eccezioni, non il gestore degli errori. Il gestore degli errori sta causando l'effettivo problema discusso qui con errori irreversibili irreversibili ( E_RECOVERABLE_ERROR
) .
PHP 7 e HHVM lo hanno già risolto.
È peggio con Magento perché il gestore degli errori non si occupa di questo dalla classe di errore PHP 5.2.
Un tipo più utile di gestione degli errori sarebbe gestire questa classe di errori e trasformare questi errori in ErrorException s. Esempio (non da me, da qui ):
set_error_handler(function($errno, $errstr, $errfile, $errline) {
if ($errno === E_RECOVERABLE_ERROR) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
return false;
});
Quindi alla luce di Magento, il gestore degli errori predefinito è la funzione globale mageCoreErrorHandler
in app/code/core/Mage/Core/functions.php
. Viene registrato tramite Mage::app()
il init()
metodo di Mage_Core_Model_App ( app/code/core/Mage/Core/Model/App.php
) (tramite _initEnvironment()
metodo protetto ).
Un osservatore sucontroller_front_init_before
cui registra il proprio gestore di errori PHP in alto dovrebbe essere sufficiente (i gestori di errori in PHP sono impilabili):
$previous = set_error_handler(function($errno, $errstr, $errfile, $errline) use (&$previous) {
if ($errno === E_RECOVERABLE_ERROR) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
if ($previous) {
return call_user_func($previous, $errno, $errstr, $errfile, $errline);
}
return false;
});
errori irreversibili irreversibili vengono poi trasformati in eccezioni e puoi gestirli nel tuo codice di estensione o non sono rilevati e verranno visualizzati nel registro delle eccezioni (invece di far eseguire al tuo negozio gaga su tipi errati come il comportamento attuale, programmi morti non mentire ). In PHP 7 l'eccezione di cercare non è ErrorException allora, ma TypeException (che è un BaseException ) per l'ormai errori fatali catturabile .
Tutti gli altri errori vengono passati al gestore errori di Magento.
Nota: non l'ho provato, è un articolo di scrittura ma conosco il problema che stai chiedendo e l'analisi della gestione degli errori è stata eseguita su 1.5.1.0 e verificata su 1.9.1.0 tramite analisi del codice. L'impilamento del gestore errori dovrebbe funzionare. Aggiungo un piccolo esempio di codice che mostra la maggior parte delle parti funzionanti.
Non l'ho ancora impacchettato come estensione magento ma dovrebbe essere semplice con modman. Lo metterò su Github allora.
Appendice: demo del gestore degli errori
Il seguente esempio di codice ( demo online ) mostra l'accatastamento di gestori di errori e l'eccezione che genera errori irreversibili irreversibili :
<?php
/**
* error handler demonstration
*
* stackable error handle with previous call and catchable error exceptions
*
* @author hakre <http://hakre.wordpress.com>
* @link /magento//a/64972/4115
*/
set_error_handler(function() {
$args = func_get_args();
var_dump("me is the previous error handler", $args);
});
$previous = set_error_handler(function($errno, $errstr, $errfile, $errline) use (&$previous) {
if ($errno === E_RECOVERABLE_ERROR) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
if ($previous) {
return call_user_func($previous, $errno, $errstr, $errfile, $errline);
}
return false;
});
$test = function(callable $test) {};
$a = $undefined; // provoke little warning
$test(new stdClass); // provoke catchable fatal error
Uscita del programma
string(32) "me is the previous error handler"
array(4) {
[0]=>
int(8)
[1]=>
string(29) "Undefined variable: undefined"
[2]=>
string(45) "/tmp/execpad-0eca072b619d/source-0eca072b619d"
[3]=>
int(28)
}
Fatal error: Uncaught exception 'ErrorException' with message 'Argument 1 passed to {closure}() must be callable, object given, called in /tmp/execpad-0eca072b619d/source-0eca072b619d on line 30 and defined' in /tmp/execpad-0eca072b619d/source-0eca072b619d:26
Stack trace:
#0 /tmp/execpad-0eca072b619d/source-0eca072b619d(26): {closure}(4096, 'Argument 1 pass...', '/tmp/execpad-0e...', 26, Array)
#1 /tmp/execpad-0eca072b619d/source-0eca072b619d(30): {closure}(Object(stdClass))
#2 {main}
thrown in /tmp/execpad-0eca072b619d/source-0eca072b619d on line 26