Wojciech Sznapka

Wojciech Sznapka CTO @ STS Zakłady
Bukmacherskie

Temat: Jakikolwiek sposób na obsługę fatal error

Da się? Znalazlem tylko w php.ini

error_prepend_string = "html code"
error_append_string = "html code"

ale to mnie nie odpręża. Najchętniej bym chciał status code, np 500, wtedy w ajaxie można by to jakoś łapać.

Macie doświadczenia w tym temacie?

Btw. wiem co to fatal error i wiem, że nie powinien występować, ale różne rzeczy się czasem dzieją...
Michał Jarosz

Michał Jarosz Frontend Developer &
Team Leader

Temat: Jakikolwiek sposób na obsługę fatal error

Wyłącz wyświetlanie błędów, to dostaniesz Error 500
Wojciech Sznapka

Wojciech Sznapka CTO @ STS Zakłady
Bukmacherskie

Temat: Jakikolwiek sposób na obsługę fatal error

Michał Jarosz:
Wyłącz wyświetlanie błędów, to dostaniesz Error 500

Faktycznie :-) Kurde, za dużo używam środowiska dev w sf :-)
Paweł G.

Paweł G. Managing Director

Temat: Jakikolwiek sposób na obsługę fatal error

My to zrobiliśmy tak.

Na początku skryptu:


register_shutdown_function('shutdown');


Sama funkcja ma taką postać:


$isError = false;
if ($error = error_get_last()){
switch($error['type']){
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
$isError = true;
break;
}
}
if ($isError){
echo "Script execution halted ({$error['message']})";
$type = 'ERROR';
/*
tutaj jakies inne akcje np. wyslanie maila z info
*/
}


Funkcja ta jest wykonywana tuż przed zakończeniem działania skryptu, co musi nastąpić z uwagi na fatal error.
Dzięki temu rozwiązaniu ma natychmiastową informacje o błędzie
i możemy podjąć odpowiednie kroki.
Wojciech Sznapka

Wojciech Sznapka CTO @ STS Zakłady
Bukmacherskie

Temat: Jakikolwiek sposób na obsługę fatal error

Paweł G.:
My to zrobiliśmy tak.

Na początku skryptu:


register_shutdown_function('shutdown');


Sama funkcja ma taką postać:


$isError = false;
if ($error = error_get_last()){
switch($error['type']){
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
$isError = true;
break;
}
}
if ($isError){
echo "Script execution halted ({$error['message']})";
$type = 'ERROR';
/*
tutaj jakies inne akcje np. wyslanie maila z info
*/
}


Funkcja ta jest wykonywana tuż przed zakończeniem działania skryptu, co musi nastąpić z uwagi na fatal error.
Dzięki temu rozwiązaniu ma natychmiastową informacje o błędzie
i możemy podjąć odpowiednie kroki.

to niestety nie działa: http://pastebin.com/f36691ee3
Paweł G.

Paweł G. Managing Director

Temat: Jakikolwiek sposób na obsługę fatal error

Wojciech Sznapka:
to niestety nie działa: http://pastebin.com/f36691ee3

Ale tam masz parse error, a nie fatal error, a to jest różnica.
Z tego co wiem, to nie da się w żaden sposób tego ominąć.

Podana przeze mnie kod działa prawidłowo przy błędzie typu wywołanie niezadeklarowanej funkcji.
Wojciech Sznapka

Wojciech Sznapka CTO @ STS Zakłady
Bukmacherskie

Temat: Jakikolwiek sposób na obsługę fatal error

sorry, widocznie niedoprecyzowałem - chodziło mi również o parse errory, ale faktycznie, przy wyłączonym wyświetlaniu błędów serwer serwer rzuca kod 500 i to mi wystarcza do obsługi z poziomu ajax.

konto usunięte

Temat: Jakikolwiek sposób na obsługę fatal error

Wojciech Sznapka:
Da się? Znalazlem tylko w php.ini

error_prepend_string = "html code"
error_append_string = "html code"

ale to mnie nie odpręża. Najchętniej bym chciał status code, np 500, wtedy w ajaxie można by to jakoś łapać.

Macie doświadczenia w tym temacie?

Btw. wiem co to fatal error i wiem, że nie powinien występować, ale różne rzeczy się czasem dzieją...


function exception_error_handler($errno, $errstr, $errfile, $errline ) {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");

/* To wyrzu wyjątek */
strpos();


Taki wyjątek można bez problemu złapać i odpowiednio obsłużyć.
W wyniku dostaniemy np.:


Fatal error: Uncaught exception 'ErrorException' with message 'Wrong parameter count for strpos()' in /home/bjori/tmp/ex.php:8
Stack trace:
#0 [internal function]: exception_error_handler(2, 'Wrong parameter...', '/home/bjori/php...', 8, Array)
#1 /home/bjori/php/cleandocs/test.php(8): strpos()
#2 {main}
thrown in /home/bjori/tmp/ex.php on line 8


Jednak moim zdaniem łapanie fatal error jest mało rozsądnym pomysłem. Kod z takimi błędami pod żadnym pozorem nie powinien trafić na produkcję.
Michał Płonka

Michał Płonka Programista PHP

Temat: Jakikolwiek sposób na obsługę fatal error

Można przechwycić wszystkie errory świata ;) poprzez buforowanie wyjścia. Tutaj jest przykład:
http://forums.knownhost.com/showthread.php?t=1080
Na podstawie tego mam napisaną klasę, która przechwytuje wszystkie błędy i wrzuca je do bazy danych wyświetlając przy tym użytkownikowi informacje o wystąpieniu błędu oraz podając ID ticketu błędu. Dzięki temu użytkownik może przekazać administratorowi systemu, że wystąpiły błędy o tickecie np. 100, a admin może podejrzeć te błędy w bazie danych. Dodatkowo w trybie dev dopisałem sobie podgląd plików i linijek, które powodują błąd.

Generalnie sprawdza się to całkiem przyzwoicie, a zwykły użytkownik nie ma prawa zobaczyć niczego poza stroną błędu.

Jest tylko jeden minus takiego rozwiązania. Nie jest ono bowiem dobrym znajomym wydajności właśnie z racji buforowania i konieczności sprawdzania danych z bufora wyrażeniem regularnym - no ale coś za coś...
Michał Jarosz

Michał Jarosz Frontend Developer &
Team Leader

Temat: Jakikolwiek sposób na obsługę fatal error

Łukasz Bandzarewicz:


set_error_handler("exception_error_handler");

Ani Fatal, ani Parse Error tym nie złapiesz.
Jednak moim zdaniem łapanie fatal error jest mało rozsądnym
pomysłem. Kod z takimi błędami pod żadnym pozorem nie powinien
trafić na produkcję.
>

Wiele rzeczy nie powinno trafić na produkcję a trafiło ;) Wiesz jak się wkurzyłem, jak kiedyś MediaWiki zaczęła mi wywalać stack trace na ekran? Akurat z funkcji, która łączy się z bazą, więc wszystkie dane na wierzchu.

konto usunięte

Temat: Jakikolwiek sposób na obsługę fatal error

Apropos fatal errors:

http://www.vimeo.com/tag:wywalmifatalerrora


Fatal error: Call to a member function isEmailVerified() on a non-object in /home/production/vimeo/controllers/vimeo.controller.browse.php on line 274


Jak widać, nawet najwięksi mają z tym problemy ;-)
Marek H.

Marek H. Web developer

Temat: Jakikolwiek sposób na obsługę fatal error

Marcin Olichwirowicz:

Fatal error: Call to a member function isEmailVerified() on a non-object in /home/production/vimeo/controllers/vimeo.controller.browse.php on line 274


Jak widać, nawet najwięksi mają z tym problemy ;-)

Nie tyle najwięksi, co PHP, które nie dość, że nie umie przechwytywać tego typu błędów, to jeszcze nie zna pojęcia NullPointerException, dzięki czemu wiązki typu $x->a()->b(); często mają szansę zakończyc się Fatal Errorem właśnie. Jeśli by chcieć temu zapobiec, kod w jakichś 30% musiałby się składać z konstrukcji if (isset($x)) {...}. Nie zgadzam się zatem ze stwierdzeniem, że Fatal Error nigdy nie ma prawa przytrafić się dobremu programiście (co jest konsekwencją zdania, że kod podatny na Fatal Errory nigdy nie powinien trafić na produkcję). Owszem, programiście chluby to nie przynosi, ale sporo od siebie dodaje niedopracowane PHP.

W PHP 6 ma być ponoć łapanie Fatal Errorów.

konto usunięte

Temat: Jakikolwiek sposób na obsługę fatal error

Marek H.:
Marcin Olichwirowicz:

Fatal error: Call to a member function isEmailVerified() on a non-object in /home/production/vimeo/controllers/vimeo.controller.browse.php on line 274


Jak widać, nawet najwięksi mają z tym problemy ;-)

Nie tyle najwięksi,

Vimeo to dość spory serwis :)
co PHP, które nie dość, że nie umie przechwytywać tego typu błędów, to jeszcze nie zna pojęcia NullPointerException, dzięki czemu wiązki typu $x->a()->b(); często mają szansę zakończyc się Fatal Errorem właśnie.

Powtarzasz to co już było tu napisane ;)
Jeśli by chcieć temu zapobiec, kod w jakichś 30% musiałby się składać z konstrukcji if (isset($x)) {...}.

Wrażliwe części powinny być obwarowane takimi instrukcjami, wystarczy if (is_object($x)).
Nie zgadzam się zatem ze stwierdzeniem, że Fatal Error nigdy nie ma prawa przytrafić się dobremu programiście (co jest konsekwencją zdania, że kod podatny na Fatal Errory nigdy nie powinien trafić na produkcję). Owszem, programiście chluby to nie przynosi, ale sporo od siebie dodaje niedopracowane PHP.

Ale ja nigdzie nie pisałem takich stwierdzeń ;-)
W PHP 6 ma być ponoć łapanie Fatal Errorów.

O mitach i podaniach na temat PHP6 słyszę od hmm... 3 lat. Od jakiegoś czasu traktuję to jakoś z przymrużeniem oka i lekkim uśmiechem ;)
Marek H.

Marek H. Web developer

Temat: Jakikolwiek sposób na obsługę fatal error

W odpowiedzi...
Nie tyle najwięksi,

Vimeo to dość spory serwis :)

Ależ nie kwestionuję, chodziło mi o to, że wielkość serwisu nie jest tutaj wyznacznikiem.
Powtarzasz to co już było tu napisane ;)

No tak... Ale to dlatego, że PHP w dalszym ciągu sobie z tym nie radzi ;-) Jutro zatem tez o tym tu napiszę :P
Wrażliwe części powinny być obwarowane takimi instrukcjami, wystarczy if (is_object($x)).

No, skoro jest jak jest to nie ma wyjścia, ale z wygodą programisty ma to mało wspólnego. Po to wymyślono wyjątki, żeby (między innymi) zaoszczędzić na kaskadzie if-ów.
Nie zgadzam się zatem ze stwierdzeniem, że Fatal Error nigdy nie ma prawa przytrafić się dobremu programiście (co jest konsekwencją zdania, że kod podatny na Fatal Errory nigdy nie powinien trafić na produkcję). Owszem, programiście chluby to nie przynosi, ale sporo od siebie dodaje niedopracowane PHP.

Ale ja nigdzie nie pisałem takich stwierdzeń ;-)

Parę wypowiedzi powyżej ktoś napisał, że kod podatny na Fatal Errory nigdy nie powinien znaleźć się na produkcji i ja się odnoszę do tej właśnie wypowiedzi. Gwoli ścisłości - to nie byłeś Ty :)
O mitach i podaniach na temat PHP6 słyszę od hmm... 3 lat. Od jakiegoś czasu traktuję to jakoś z przymrużeniem oka i lekkim uśmiechem ;)

Nic dodać, nic ująć :)

konto usunięte

Temat: Jakikolwiek sposób na obsługę fatal error

Fatal errora obsłużysz tylko i wyłącznie gdybyś bufferował cały skrypt. Ale i tak gdzieś trzeba zakończyć bufferowanie i wypluć kod, także w 100% praktycznie tego się nie da zrobić.
Artur Świerc

Artur Świerc Programista PHP/Java

Temat: Jakikolwiek sposób na obsługę fatal error

Marek H.:
W PHP 6 ma być ponoć łapanie Fatal Errorów.

Powinni przerobić wszystkie errory na wyjątki, a nie umożliwiać tylko ich łapanie. Nie mniej teraz error handler i wyrzucanie błędów jako wyjątki jest pewną namiastką "normalnego" języka :)Artur Świerc edytował(a) ten post dnia 22.09.10 o godzinie 21:12
Jarosław Lisicki

Jarosław Lisicki programista,
Gadu-Gadu

Temat: Jakikolwiek sposób na obsługę fatal error

Krótki test i wydaje się, że da się łapać zarówno parse error jak i fatal error. Warunek dla parse error - register_shutdown_function musi byc w pliku ktory sie poprawnie sparsuje i jest ładowany przed błędem :)

<?php

//ini_set('display_errors',0);
register_shutdown_function('shutdown');

function shutdown()
{
$e = error_get_last();
var_dump($e);
}

require 'test.php';

test.php - wariant 1:
<?php

$obj = new stdClass();
$obj->method();

test.php - wariant 2:
<?php

echo 'test';
test
Michał Jarosz

Michał Jarosz Frontend Developer &
Team Leader

Temat: Jakikolwiek sposób na obsługę fatal error

Marek H.:

W PHP 6 ma być ponoć łapanie Fatal Errorów.

substr('W PHP 6 ma być ponoć łapanie Fatal Errorów.',2,18)



Wyślij zaproszenie do