Buena pregunta. Creo que este es un problema general E_RECOVERABLE_ERROR
en PHP.
Lo que tiene en su pregunta es el controlador de excepciones, no el controlador de errores. El controlador de errores está causando el problema real que discute aquí con errores fatales detectables ( E_RECOVERABLE_ERROR
) .
PHP 7 y HHVM ya tienen esto resuelto.
Es peor con Magento porque el controlador de errores no se ocupa de esto desde la clase de error PHP 5.2.
Un tipo más útil de manejo de errores sería tratar con esta clase de error y convertir estos errores en ErrorException s. Ejemplo (no por mí, desde aquí ):
set_error_handler(function($errno, $errstr, $errfile, $errline) {
if ($errno === E_RECOVERABLE_ERROR) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
}
return false;
});
Entonces, a la luz de Magento, el controlador de errores predeterminado es la función global mageCoreErrorHandler
en app/code/core/Mage/Core/functions.php
. Se registra a través Mage::app()
del init()
método de Mage_Core_Model_App ( app/code/core/Mage/Core/Model/App.php
) (a través del _initEnvironment()
método protegido ).
Entonces debería ser suficiente un observadorcontroller_front_init_before
que registre su propio controlador de errores PHP en la parte superior (los controladores de errores en PHP son apilables):
$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;
});
los errores fatales detectables se convierten en excepciones y puede tratarlos en su propio código de extensión o no se detectan y se verán en el registro de excepciones (en lugar de que su tienda ejecute gaga en tipos incorrectos como el comportamiento actual es, programas muertos) no mientas ) En PHP 7, la excepción a buscar no es ErrorException , sino TypeException (que es una BaseException ) para los errores fatales ahora detectables .
Todos los demás errores se pasan al controlador de errores de Magento.
Nota: No he intentado esto, es una redacción, pero sé el problema sobre el que está preguntando y el análisis de manejo de errores se realizó en 1.5.1.0 y se verificó en 1.9.1.0 a través del análisis de código. El apilamiento del controlador de errores debería funcionar. Adjunto un pequeño código de ejemplo extendido que demuestra que la mayoría de las partes funcionan.
Todavía no he empaquetado esto como una extensión de magento, pero debería ser sencillo con modman. Lo pondré en github entonces.
Apéndice: Demo del controlador de errores
El siguiente ejemplo de código ( demostración en línea ) demuestra el apilamiento de los manejadores de errores y el lanzamiento de excepciones ante errores fatales detectables :
<?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
Programa de salida
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