Dobre pytanie. Myślę, że jest to ogólny problem E_RECOVERABLE_ERROR
w PHP.
To, co masz w swoim pytaniu, to procedura obsługi wyjątków, a nie procedura obsługi błędów. Program obsługi błędów powoduje rzeczywisty problem, który tutaj omawiasz,E_RECOVERABLE_ERROR
z możliwymi do wykrycia błędami krytycznymi ( ) .
PHP 7 i HHVM już to rozwiązały.
Gorzej z Magento, ponieważ program obsługi błędów nie radzi sobie z tym od klasy błędów PHP 5.2.
Bardziej użytecznym rodzajem obsługi błędów byłoby radzenie sobie z tą klasą błędów i zamiana tych błędów w ErrorException s. Przykład (nie przeze mnie, stąd ):
set_error_handler(function($errno, $errstr, $errfile, $errline) {
if ($errno === E_RECOVERABLE_ERROR) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
return false;
});
Tak więc w świetle Magento domyślną obsługą błędów jest funkcja globalna mageCoreErrorHandler
w app/code/core/Mage/Core/functions.php
. Zostaje zarejestrowany za Mage::app()
pomocą init()
metody Mage_Core_Model_App ( app/code/core/Mage/Core/Model/App.php
) (za pomocą _initEnvironment()
metody chronionej ).
W takim przypadku wystarczy obserwator, nacontroller_front_init_before
którym rejestruje się własny program obsługi błędów PHP (programy obsługi błędów w PHP można ustawiać jeden na drugim):
$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;
});
wykrywalne błędy krytyczne są następnie przekształcane w wyjątki i można sobie z nimi poradzić we własnym kodzie rozszerzenia lub są one niewyłapane i będą widoczne w dzienniku wyjątków (zamiast tego, że sklep uruchamia gaga na niewłaściwych typach, takich jak obecne zachowanie, martwe programy nie kłam ). W PHP 7 wyjątkiem, którego należy szukać, nie jest ErrorException, ale TypeException (który jest BaseException ) dla wykrywalnych obecnie błędów krytycznych .
Wszystkie pozostałe błędy są przekazywane do modułu obsługi błędów Magento.
Uwaga: nie próbowałem tego, jest to zapis, ale znam problem, o który pytasz, a analiza obsługi błędów została wykonana w stosunku do wersji 1.5.1.0 i zweryfikowana w stosunku do wersji 1.9.1.0 poprzez analizę kodu. Układanie procedur obsługi błędów powinno działać. Dołączam trochę rozszerzonego przykładowego kodu, który pokazuje, że większość części działa.
Nie spakowałem tego jeszcze jako rozszerzenia Magento, ale powinno być prosto z Modmanem. W takim razie włożę to na github.
Dodatek: Demonstracja modułu obsługi błędów
Poniższy przykład kodu ( demonstracja online ) demonstruje układanie programów obsługi błędów i zgłaszanie wyjątków w przypadku krytycznego błędu krytycznego :
<?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
Wyjście programu
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