Czy błąd tłumi złe praktyki?


14

Na pytanie SO, które tu zadałem , na temat jakiegoś kodu, którego nie byłem pewien, ktoś odpowiedział: „BTW, okropny kod: często używa symbolu tłumiącego błędy (@)”.

Czy istnieje powód, dla którego jest to zła praktyka? Z takimi rzeczami jak:

$db=@new mysqli($db_info) or die('Database error');

, pozwala mi wyświetlić tylko niestandardowy komunikat o błędzie. Bez tłumienia błędów nadal wyświetlałby typowy komunikat PHP:

Ostrzeżenie : mysqli :: mysqli (): php_network_getaddresses: getaddrinfo nie powiodło się: Żaden taki host nie jest znany. w ścieżce \ file \ w wierszu 6

a także „Błąd bazy danych”.

Czy eliminowanie błędów jest zawsze złe, a jeśli tak, to co konkretnie w powyższym jest złe?

Aktualizacja: faktyczny kod, którego używam to:

or error('Datatabase error', 'An error occurred with the database' . (($debug_mode) ? '<br />MySQL reported: <b>' . $db->error . '</b><br />Error occurred on line <b>' . __LINE__ . '</b> of <b>' . __FILE__ . '</b>' : ''))

który usuwa wszystkie poprzednie dane wyjściowe i wyświetla komunikat o błędzie. Zatem fakt, że komunikat o błędzie nie zawiera szczegółowych informacji o tym, co się konkretnie wydarzyło (co ludzie sugerują jako przyczynę złego tłumienia błędów) jest nieistotny.


9
Czy nosisz opaskę podczas jazdy złym treningiem?
Damien Roche

Jak może to być poważne pytanie? Myślę, że jeśli lubisz pisać kod, którego debugowanie zajmuje wiele godzin, dobrym pomysłem byłoby wyeliminowanie błędów. Pomyśl o tym, aplikacja nie działa, uszkadza dane ... i nie chcesz wiedzieć, dlaczego ani gdzie w kodzie. Kiedy to będzie dobry pomysł? Musisz zaprosić swoich znajomych, aby przeprowadzili na tobie imprezę kocową ... to ta sama logika.
Some Free Mason

1
@SomeFreeMason Gdybym musiał debugować, po prostu ustawiłbym $ debug_mode na PRAWDA, ponieważ rzeczywisty kod, którego używam to:or error('Datatabase error', 'An error occurred with the database' . (($debug_mode) ? '<br />MySQL reported: <b>' . $db->error . '</b>' : ''))

@ Paradoxical: Zdaję sobie sprawę, że stan obsługi wyjątków / błędów w PHP jest trochę FUBAR, ale zdajesz sobie sprawę, że możesz wyłączyć wizualne wyświetlanie błędów w konfiguracji PHP, prawda?
Phoshi

@ Phoshi niestety usługa hostingowa, z której korzystam, nie daje mi dostępu do php.ini

Odpowiedzi:


14

Myślę, że postępujesz właściwie, tłumiąc błąd, ponieważ wdrażasz własną obsługę błędów.

Łatwiej byłoby rozważyć odpowiednik np. W Javie. Pomijanie błędu przy użyciu @jest analogiczne do połykania wyjątku. Poniższy kod, podobny do twojego, jest rozsądny:

try {
    db = new MySQLi(dbInfo);
} catch (SQLException connectionFailure) {
    die("Database error");
}

(Cóż, w Javie nie chciałbyś, aby silnik serwletu zginął, ale masz pomysł.)

Nie jest to jednak dopuszczalne:

try {
    db = new MySQLi(dbInfo);
} catch (Exception e) {
}

Większość eliminacji błędów PHP odbywa się niedbale, analogicznie do drugiego przykładu, stąd reakcja kolana na twój kod.


3
Nie zadzwoniłbym do przechwytywania wyjątku i po prostu zatrzymywania wykonywania, aby go „obsłużyć”. Jeśli możesz rozwiązać problem, świetnie, zrób to. Jeśli nie możesz, co do diabła robisz, łapiąc go? Do tego mamy programy obsługi wyjątków najwyższego poziomu. Łapanie wyjątków w tym przypadku polega tylko na upewnieniu się, że kod obsługi błędów jest rozrzucony po całej bazie kodu.
Phoshi

7

Eliminowanie błędów jest złe, ponieważ nie tylko ukrywa informacje, które już znasz ( coś poszło nie tak). Może także ukrywać informacje niezbędne do debugowania, których nie jesteś świadomy ( co , gdzie i dlaczego ).

W tym konkretnym przykładzie „ Błąd bazy danych ” nie jest bardzo dobrym komunikatem o błędzie. Coś poszło nie tak z DB. Niezbyt pouczające. „ Ostrzeżenie: mysqli :: mysqli (): php_network_getaddresses: getaddrinfo nie powiodło się: Żaden taki host nie jest znany. w jakimś \ pliku \ ścieżce w linii 6 ”jest w rzeczywistości lepszy komunikat o błędzie. Podaje lokalizację i przyczynę problemu. Możesz od razu wskoczyć i rozpocząć debugowanie, ponieważ błąd został już zlokalizowany.

Oczywiście, projektanci bibliotek czasami mają tendencję do przywoływania wielu nieistotnych ostrzeżeń. Nie znam PHP wystarczająco dobrze, aby wiedzieć, czy ma sposób na odfiltrowanie ostrzeżeń, które Cię nie interesują. Wiem, że czytanie przez setkę linii stacktrace nie jest zbyt pouczające. Ale prawidłowa odpowiedź na zbyt wiele informacji nie polega na zmniejszeniu ilości informacji do zera , ale na pewnym etapie odfiltrowaniu nieistotnych części. @Operator nie ma tego ziarnistość (to motto to wszystko albo nic ), a zatem nie jest odpowiednim narzędziem do efektywnego zarządzania błędu.

Istnieją przypadki, gdy wiesz, że pewien błąd będzie podkręcić, a ustalenia rzeczywistego problemu jest droższe niż wyciszanie komunikat (i cierpienie potencjalnego fallout od tego). Może tak być w przypadku jednorazowego skryptu, ale wbicie palców w uszy i „ la la lanie jest profesjonalną reakcją na (potencjalne) błędy.


5
Nie chcesz informować użytkowników o dokładnym błędzie. Poinformujesz ich, że błąd jest po twojej stronie i że nad tym pracujesz. Możesz rejestrować błędy na serwerze i konfigurować alerty, abyś automatycznie o nich wiedział, ale nie ma powodu, aby wyświetlać te błędy użytkownikowi.
Jeroen Vannevel

1
Czy na stronie działającej z pewnością lepiej byłoby wyświetlać komunikat o błędzie, który typowy użytkownik może zrozumieć, niż „jakieś techniczne śmieci związane z mysqli, cokolwiek to jest”? Gdybym próbował go debugować, usunąłem eliminację błędów, ale w działającej witrynie nie zgadzam się, aby wyświetlić pełny błąd.

3
@ Paradoxical Na poważnej stronie nie wyświetla się komunikat o błędzie, taki jak „błąd bazy danych” i nic więcej. Wyświetliłaby się ogólna strona „wewnętrzny błąd serwera” z dużą ilością puchu, stylizacji, stopki itp., Która dienie jest odpowiednia dla żadnego z nich. A szczegółowe informacje powinny przejść do dziennika, niezależnie od tego, co wyświetlasz użytkownikowi .

1
Czy nie ma sposobu, aby wyświetlić przyjazny dla użytkownika komunikat na ekranie i zapisać komunikat techniczny w pliku dziennika?
FrustratedWithFormsDesigner

3
display_errorswyłącz, włącz log_errorsi jesteś całkiem dobry, zrób to, co chcesz, po wykryciu błędu, ale nie wyrzucaj go.
Wrikken

0

Eliminowanie błędów jest złe, ponieważ ukrywa problem, o którym niejednokrotnie nawet nie jesteśmy świadomi, i może powodować nieoczekiwane zachowanie, które może okazać się bardzo kosztowne w niektórych krytycznych aplikacjach, np. W aplikacjach używanych w domenach finansowych, zdrowotnych i obronnych.

Nie jest również dobrym pomysłem, aby nieobsługiwane wyjątki w kodzie i wyświetlać użytkownikowi rzeczywiste komunikaty o błędach, ponieważ może to powodować problemy z bezpieczeństwem, ponieważ komunikaty o błędach zwykle ujawniają wiele informacji o kodzie, co może pomóc złośliwym użytkownikom i hakerom w manipulowaniu system.

Tak więc dobrą praktyką jest radzenie sobie z błędami na różnych poziomach, np. Na najwyższym poziomie możesz poradzić sobie z błędem, po prostu logując się do rzeczywistego błędu i pokazując użytkownikowi prosty i przyjazny komunikat.


0

Tak, operator eliminujący błędy jest ogólnie złym pomysłem.

Powinieneś zarządzać raportowaniem błędów w konfiguracji ( php.ini). Możesz więc wybrać inne ustawienie dla każdego środowiska (np. Pozostaw ostrzeżenia w fazie rozwoju i ukryj je w środowisku produkcyjnym).

Jedyną sytuacją, w której użycie @może mieć sens, jest tworzenie biblioteki dla innych programistów. Jeśli zdecydujesz się zrobić coś, co spowoduje wyświetlenie ostrzeżenia i nie chcesz drażnić użytkowników swojej biblioteki ostrzeżeniem, które nie zależy od nich, @może to być rozwiązanie.

Nie mogę wymyślić żadnego innego zastosowania.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.