Dobre pytanie +1
Przeprowadziłem badania i testy po dobrym punkcie w kierunku po mojej dyskusji z @mpw na mojej pierwszej odpowiedzi. Po raz pierwszy częściowo to źle zrozumiałem.
Dodam trochę kodu, aby wyjaśnić, aby inni lepiej zrozumieli problem.
Notatka przed startem
Nigdy nie miałem takich problemów, dopóki to się nie wydarzyło. Rozwijając się w Magento z włączonym trybem programisty, nawet o tym nie myślę. Więc za każdym razem, gdy pierdnę , pojawi się i zostanie odpowiednio poprawiony.
Problem z próbką wyjaśniającą
Twoje krytyczne błędy mówienia zostaną zarejestrowane (jeśli włączone), a kod będzie kontynuowany jak zwykle, ponieważ żaden błąd nie zostanie zgłoszony mageCoreErrorHandler
ani program nie exit
.
Podstawowa procedura obsługi błędów Magento w przypadku błędów niewykrywalnych 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);
}
}
Jak widać, w trybie programisty powie coś pożytecznego, zgłasza błąd. Po wyłączeniu rejestruje się (jeśli jest włączone) i kontynuuje.
Dowód
Mój 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');
}
Wynik
Tryb programowania włączony. Prawidłowy wynik
string(5) "hello"
string(66) "You should die, because I am doing something which I should not do"
Tryb programowania wyłączony, niepoprawny wynik
string(5) "hello"
string(61) "Do not show me because Mage_Core_Model_App is not a customer."
string(16) "And we are here!"
Więc w końcu pominie błąd i przejdzie do następnego wiersza kodu. Może z jeszcze dziwniejszym rezultatem. (jak wskazuje @mpw)
Wniosek
To mogło się zdarzyć, że ktoś rozwija się w taki sposób, że błędy przejdzie niezauważony i będzie ostatecznie dać nieoczekiwane rezultaty.
Oczywiście przy profesjonalnym rozwoju. Błędy będą być zauważone i uwaga jest wypłacana. Sposobem na uniknięcie tego w Magento jest zawsze włączenie trybu programistycznego w środowisku programistycznym / testowym.
IMHO nigdy nie powinien przejść do tego punktu dyskusji, w którym sprawdzanie zmiennej po raz drugi (przynajmniej tak to opisałbym) jest właściwą drogą. Kod powinien zostać przetestowany przed wydaniem w środowiskach produkcyjnych. To powinno nie być potrzebne.
Namysł
Może Magento powinien zatrzymać się po fatalnym błędzie. Lub wygeneruj raport i pokaż go odwiedzającemu. W ten sposób kolejne wiersze kodu nigdy nie zostaną wykonane i wszystko zostanie zauważone.
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 ):
Tak więc w świetle Magento domyślną obsługą błędów jest funkcja globalna
mageCoreErrorHandler
wapp/code/core/Mage/Core/functions.php
. Zostaje zarejestrowany zaMage::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, na
controller_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):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 :
Wyjście programu
źródło
Jest już obsługiwany domyślnie przez PHP poprzez dodanie
(Exception $e)
definicji parametru funkcji.Do tej funkcji nie można przekazać niczego poza wyjątkiem lub rozszerzeniem wyjątku.
źródło
mageCoreErrorHandler
funkcję. Błąd wywołany przez niepoprawne parametry zostanie obsłużony i zniesiony w trybie innym niż programista, a takżeException
w trybie deweloperskim.mageCoreErrorHandler
mieć pewność, że odwiedzający nie otrzymają błędu w ich twarz. Możesz zbudować własny,try{}catch(){}
aby sam je złapać, a jeśli nie możesz ich przekazać.