Boa pergunta +1
Fiz algumas pesquisas e testes após um bom ponto na direção após minha discussão com @mpw na minha primeira resposta. Eu parcialmente entendi errado da primeira vez.
Adicionará algum código para esclarecer, para que outras pessoas entendam melhor o problema.
Uma nota antes de decolar
Eu nunca tive esses problemas até isso aparecer. Desenvolvendo no Magento com o modo de desenvolvedor ativado, eu nem penso um segundo sobre isso. Então, toda vez que peido , ele aparecerá e será corrigido de acordo.
O problema com uma amostra explicativa
Sua declaração de erros fatais será registrada (se ativada) e o código continuará normalmente, porque nenhum erro é gerado mageCoreErrorHandler
ou o programa seráexit
.
Primeiro manipulador de erros do Magento para erros inatacáveis app/code/core/Mage/Core/functions.php
/**
* Custom error handler
*
* @param integer $errno
* @param string $errstr
* @param string $errfile
* @param integer $errline
*/
function mageCoreErrorHandler($errno, $errstr, $errfile, $errline){
/**
* Some internal logic here for building the error message
*/
$errorMessage .= ": {$errstr} in {$errfile} on line {$errline}";
if (Mage::getIsDeveloperMode()) {
throw new Exception($errorMessage);
} else {
Mage::log($errorMessage, Zend_Log::ERR);
}
}
Como você pode ver, no modo de desenvolvedor, ele diz algo útil, gera um erro. Quando desligado, ele registrará (se ativado) e continuará.
A prova
Minhas testfile.php
require 'app/Mage.php';
Mage::app('admin')->setUseSessionInUrl(false);
// Test function which expect Customer_Model_Customer
function test(Customer_Model_Customer $customer)
{
var_dump('Do not show me because ' . get_class($customer) . ' is not a customer.');
}
// Enabled developer mode
Mage::setIsDeveloperMode(true);
// Put a var in here
$noGood = Mage::app();
// Make some context
var_dump('hello');
try {
// Call test function with a not accepted var
test($noGood);
// Tell if we get here
var_dump('And we are here!');
} catch (Exception $e) {
var_dump('You should die, because I am doing something which I should not do');
}
O resultado
Modo de desenvolvedor ativado. Resultado correto
string(5) "hello"
string(66) "You should die, because I am doing something which I should not do"
Modo do desenvolvedor desativado, resultado incorreto
string(5) "hello"
string(61) "Do not show me because Mage_Core_Model_App is not a customer."
string(16) "And we are here!"
Portanto, ele eventualmente pulará o erro e continuará na próxima linha de código. Talvez com resultados ainda mais estranhos. (como @mpw aponta)
Conclusão
Ele poderia acontecer que alguém está se desenvolvendo de uma forma que os erros vão despercebidas e irá , eventualmente, dar resultados inesperados.
É claro que quando se desenvolve de maneira profissional. Erros vai ser notado e atenção é pago. A maneira de evitar isso no Magento é sempre ativar o modo de desenvolvedor em um ambiente de desenvolvedor / teste.
IMHO nunca deve chegar a esse ponto de discussão, onde verificar uma variável pela segunda vez (pelo menos é assim que eu descreveria) é o caminho a percorrer. O código deve ser testado antes da liberação nos ambientes de produção. Ele deve não ser necessário.
Segundas intenções
Talvez o Magento deva parar após um erro fatal. Ou gere um relatório e mostre-o ao visitante. Dessa forma, as próximas linhas de código nunca serão executadas e as coisas serão notadas.
Boa pergunta. Eu acho que esse é um problema geral
E_RECOVERABLE_ERROR
no PHP.O que você tem na sua pergunta é o manipulador de exceções, não o manipulador de erros. O manipulador de erros está causando o problema real que você discute aqui com erros fatais capturáveis (
E_RECOVERABLE_ERROR
) .PHP 7 e HHVM já resolveram isso.
É pior com o Magento porque o manipulador de erros não lida com isso desde a classe de erro do PHP 5.2.
Um tipo mais útil de tratamento de erros seria lidar com essa classe de erro e transformá-los em ErrorException s. Exemplo (não por mim, daqui ):
Portanto, à luz do Magento, o manipulador de erros padrão é a função global
mageCoreErrorHandler
noapp/code/core/Mage/Core/functions.php
. Ele é registrado viaMage::app()
peloinit()
método Mage_Core_Model_App (app/code/core/Mage/Core/Model/App.php
) (via_initEnvironment()
método protegido ).Um observador no
controller_front_init_before
qual registra seu próprio manipulador de erros PHP no topo deve ser suficiente (os manipuladores de erros no PHP são empilháveis):erros fatais capturáveis são transformados em exceções e você pode lidar com eles em seu próprio código de extensão ou eles são detectados e serão vistos no log de exceções (em vez de fazer com que sua loja execute gaga com tipos errados, como o comportamento atual, programas mortos não minta ). No PHP 7, a exceção a procurar não é ErrorException , mas TypeException (que é uma BaseException ) para os erros fatais agora capturáveis .
Todos os outros erros são passados para o manipulador de erros do Magento.
Nota: Eu não tentei isso, é uma revisão, mas eu sei o problema que você está perguntando e a análise de tratamento de erros foi feita na 1.5.1.0 e verificada na 1.9.1.0 através da análise de código. O empilhamento do manipulador de erros deve funcionar. Anexo um pequeno código de exemplo estendido que demonstra a maioria das peças funcionando.
Ainda não o empacotei como uma extensão magento, mas deve ser direta com o modman. Vou colocá-lo no github então.
Apêndice: Demonstração do Manipulador de Erros
O seguinte exemplo de código ( demonstração online ) demonstra o empilhamento de manipuladores de erros e a exceção lançando um erro fatal capturável :
Saída do Programa
fonte
Ele já é tratado pelo PHP padrão adicionando
(Exception $e)
a definição de parâmetro de função.Você não pode passar mais nada para essa função além de uma exceção ou extensão de exceção.
fonte
mageCoreErrorHandler
função. Um erro acionado por parâmetros incorretos será tratado e suprimido no modo não-desenvolvedor e lançará umException
no modo desenvolvedor.mageCoreErrorHandler
garantir que os visitantes não recebam um erro. Você pode criar um própriotry{}catch(){}
para agarrá-los você mesmo e se não puder transmiti-los.