Gute Frage. Ich denke, dies ist ein generelles Problem E_RECOVERABLE_ERROR
in PHP.
Was Sie in Ihrer Frage haben, ist die Ausnahmebehandlung, nicht die Fehlerbehandlung. Der Fehlerbehandler verursacht das eigentliche Problem, das Sie hier besprechen, mit auffindbaren schwerwiegenden Fehlern ( E_RECOVERABLE_ERROR
) .
PHP 7 und HHVM haben dies bereits gelöst.
Es ist schlimmer mit Magento, weil der Error-Handler dies seit PHP 5.2 Fehlerklasse nicht mehr behandelt.
Eine nützlichere Art der Fehlerbehandlung wäre es, sich mit dieser Fehlerklasse zu befassen und diese Fehler in ErrorException s umzuwandeln . Beispiel (nicht von mir, von hier ):
set_error_handler(function($errno, $errstr, $errfile, $errline) {
if ($errno === E_RECOVERABLE_ERROR) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
return false;
});
So im Licht von Magento, die Standard - Fehlerbehandlung ist die globale Funktion mageCoreErrorHandler
in app/code/core/Mage/Core/functions.php
. Es wird über Mage::app()
die init()
Methode der Mage_Core_Model_App ( app/code/core/Mage/Core/Model/App.php
) (über eine geschützte _initEnvironment()
Methode) registriert .
Ein Beobachter, aufcontroller_front_init_before
dem Ihr eigener PHP-Error-Handler registriert ist, sollte dann ausreichen (Error-Handler in PHP sind stapelbar):
$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;
});
Abfangbare schwerwiegende Fehler werden dann zu Ausnahmen und Sie können sie in Ihrem eigenen Erweiterungscode behandeln oder sie werden nicht abgefangen und im Ausnahmeprotokoll angezeigt (anstatt Ihren Shop auf falschen Typen laufen zu lassen, wie es das aktuelle Verhalten ist, tote Programme) lüge nicht ). In PHP 7 ist die Ausnahme, nach der gesucht werden muss, nicht ErrorException, sondern TypeException (eine BaseException ) für die jetzt auffindbaren schwerwiegenden Fehler .
Alle anderen Fehler werden an den Fehlerbehandler von Magento weitergeleitet.
Hinweis: Ich habe dies nicht ausprobiert, es ist eine Zusammenfassung, aber ich kenne das Problem, nach dem Sie fragen, und die Fehlerbehandlungsanalyse wurde mit 1.5.1.0 durchgeführt und mit 1.9.1.0 durch Codeanalyse überprüft. Das Stapeln der Fehlerbehandlungsroutine sollte funktionieren. Ich füge einen kleinen erweiterten Beispielcode an, der die meisten Teile der Arbeit demonstriert.
Ich habe dies noch nicht als Magento-Erweiterung gepackt, aber es sollte mit Modman einfach sein. Ich werde es dann auf Github setzen.
Anhang: Fehlerbehandlungs-Demo
Das folgende Codebeispiel ( Online-Demo ) veranschaulicht das Stapeln von Fehlerbehandlungsroutinen und das Auslösen von Ausnahmen bei abfangbaren schwerwiegenden Fehlern :
<?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
Programmausgabe
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