Unterdrückt ein Fehler eine schlechte Praxis?


14

Auf eine SO-Frage, die ich hier zu einem Code gestellt habe, bei dem ich mir nicht sicher war, antwortete jemand: "Übrigens, dort gibt es einen schrecklichen Code: er verwendet häufig das Symbol zur Fehlerunterdrückung (@)."

Gibt es einen Grund, warum dies eine schlechte Praxis ist? Mit Dingen wie:

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

kann ich nur eine benutzerdefinierte Fehlermeldung anzeigen. Ohne Fehlerunterdrückung würde dann immer noch die typische PHP-Nachricht von:

Warnung : mysqli :: mysqli (): php_network_getaddresses: getaddrinfo fehlgeschlagen: Es ist kein solcher Host bekannt. in irgendeinem \ file \ path in Zeile 6

sowie 'Datenbankfehler'.

Ist die Fehlerunterdrückung immer schlecht, und wenn ja, was genau ist schlecht an den oben genannten?

Update: Der aktuelle Code, den ich verwende, ist:

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>' : ''))

Dadurch werden alle vorherigen Ausgaben entfernt und eine Fehlermeldung angezeigt. Die Tatsache, dass die Fehlermeldung keine Details darüber enthält, was genau passiert ist (was offenbar als Grund für die schlechte Fehlerunterdrückung vorgeschlagen wird), ist irrelevant.


9
Trägt man eine Augenbinde, während man schlecht trainiert?
Damien Roche

Wie könnte dies eine ernste Frage sein? Ich denke, wenn Sie Code schreiben möchten, dessen Debugging Stunden in Anspruch nimmt, ist die Unterdrückung von Fehlern eine gute Sache. Denken Sie darüber nach, Ihre App schlägt fehl, beschädigt Daten ... und Sie möchten nicht wissen, warum oder wo im Code. Wann wäre das jemals eine gute Idee? Sie müssen Ihre Freunde einladen, um eine Gruppenparty für Sie zu veranstalten. Dies folgt der gleichen Logik.
Einige Free Mason

1
@SomeFreeMason Wenn ich debuggen muss, würde ich einfach $ debug_mode auf TRUE setzen, da der aktuelle Code, den ich verwende, ist:or error('Datatabase error', 'An error occurred with the database' . (($debug_mode) ? '<br />MySQL reported: <b>' . $db->error . '</b>' : ''))

@Paradoxical: Ich erkenne, dass der Ausnahmezustand / die Fehlerbehandlung in PHP etwas FUBAR ist, aber Sie wissen, dass Sie die visuelle Anzeige von Fehlern in Ihrer PHP-Konfiguration deaktivieren können, oder?
Phoshi

@Phoshi leider der Hosting-Service, den ich benutze, gibt mir keinen Zugang zu php.ini

Antworten:


14

Ich denke, Sie tun das Richtige, indem Sie den Fehler unterdrücken, weil Sie Ihre eigene Fehlerbehandlung implementieren.

Es könnte einfacher sein, das Äquivalent beispielsweise in Java zu betrachten. Das Unterdrücken des Fehlers mit @ist analog zum Verschlucken einer Ausnahme. Der folgende Code, der Ihrem ähnlich ist, ist sinnvoll:

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

(Nun, in Java möchten Sie nicht, dass die Servlet-Engine abstürzt, aber Sie haben die Idee.)

Dies ist jedoch nicht akzeptabel:

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

Die meisten PHP-Fehler werden sorglos unterdrückt, analog zu dem letztgenannten Beispiel, daher die knifflige Reaktion auf Ihren Code.


3
Ich würde nicht sagen, dass die Ausnahme abgefangen und die Ausführung angehalten wird, um sie zu "handhaben". Wenn Sie das Problem lösen können, tun Sie es. Wenn du nicht kannst, was zum Teufel machst du damit? Dafür haben wir Ausnahmebehandlungsroutinen der obersten Ebene. Wenn Sie in diesem Fall Ausnahmen abfangen, müssen Sie lediglich sicherstellen, dass auf der gesamten Codebasis Fehlerbehandlungscode verstreut ist.
Phoshi

7

Fehlerunterdrückung ist schlecht, weil es nicht nur die Informationen verstecken Sie bereits wissen ( etwas schief gelaufen ist ). Es kann auch Informationen verbergen, die für das Debuggen wichtig sind und von denen Sie nichts wissen ( was , wo und warum ).

In diesem speziellen Beispiel ist " Datenbankfehler " keine sehr gute Fehlermeldung. Bei der DB ist etwas schief gelaufen. Nicht sehr aufschlussreich. Die Warnung: mysqli :: mysqli (): php_network_getaddresses: getaddrinfo ist fehlgeschlagen: Es ist kein solcher Host bekannt. in einigen \ file \ path on line 6 "ist eigentlich eine bessere Fehlermeldung. Es gibt Ihnen einen Ort und Grund für das Problem. Sie können sofort mit dem Debuggen beginnen, da der Fehler bereits gefunden wurde.

Natürlich neigen Bibliotheksdesigner manchmal dazu, auf viele irrelevante Warnungen hinzuweisen. Ich kenne PHP nicht gut genug, um zu wissen, ob es eine Möglichkeit zum Filtern von Warnungen gibt, an denen Sie nicht interessiert sind. Die richtige Reaktion auf zu viele Informationen besteht jedoch nicht darin, die Informationsmenge auf Null zu reduzieren , sondern irgendwann irrelevante Teile herauszufiltern. Der @Bediener hat diese Granularität nicht (die Devise ist alles oder nichts ) und ist daher kein geeignetes Werkzeug für ein effektives Fehlermanagement.

In einigen Fällen wissen Sie, dass ein bestimmter Fehler auftritt und dass die Behebung des eigentlichen Problems teurer ist als das Stummschalten der Nachricht (und die daraus resultierende mögliche Beeinträchtigung). Dies könnte in einem einmaligen Skript der Fall sein, aber wenn Sie Ihre Finger in Ihre Ohren stecken und „ la la lasagen, ist dies keine professionelle Antwort auf (potenzielle) Fehler.


5
Sie möchten Ihren Benutzern nicht den genauen Fehler mitteilen. Sie informieren sie, dass der Fehler auf Ihrer Seite liegt und dass Sie daran arbeiten. Sie können die Fehler auf Ihrem Server protokollieren und Warnungen einrichten, damit Sie automatisch darüber informiert werden. Es gibt jedoch keinen Grund, diese Fehler dem Benutzer anzuzeigen.
Jeroen Vannevel

1
Auf einer Live-Site ist es sicherlich besser, wenn eine Fehlermeldung angezeigt wird, die der typische Benutzer verstehen kann, als "irgendein technischer Müll über ein Mysqli, was auch immer das ist"? Wenn ich versuche, es zu debuggen, würde ich die Fehlerunterdrückung entfernen, aber in einer Live-Site bin ich anderer Meinung, dass der vollständige Fehler angezeigt werden sollte.

3
@Paradoxical Auf einer ernsthaften Site würden Sie keine Fehlermeldung wie "Datenbankfehler" und sonst nichts anzeigen. Sie würden eine allgemeine Seite mit "internen Serverfehlern" anzeigen, die viel mehr Flaum, Styling, Fußzeile usw. enthält dieund für beide nicht geeignet ist. Die detaillierten Informationen sollten in ein Protokoll aufgenommen werden, unabhängig davon, was Sie dem Benutzer anzeigen .

1
Ist es nicht möglich, eine benutzerfreundliche Meldung auf dem Bildschirm anzuzeigen und die technische Meldung in eine Protokolldatei zu schreiben?
FrustratedWithFormsDesigner

3
display_errorsaus, log_errorsein, und Sie können so ziemlich alles tun, um einen Fehler zu entdecken, aber werfen Sie ihn nicht weg.
Wrikken

0

Das Unterdrücken von Fehlern ist schlecht, da es das Problem verbirgt, das uns oftmals gar nicht bewusst ist, und zu unerwartetem Verhalten führen kann, das sich in einigen kritischen Anwendungen als sehr kostspielig erweisen kann, z. B. in Anwendungen, die in den Bereichen Finanzen, Gesundheit und Verteidigung eingesetzt werden.

Es ist auch keine gute Idee, unbehandelte Ausnahmen im Code zu haben und dem Benutzer die tatsächlichen Fehlermeldungen anzuzeigen, da dies zu Sicherheitsproblemen führen kann, da Fehlermeldungen in der Regel viel über Ihren Code verraten, was böswilligen Benutzern und Hackern bei der Manipulation helfen kann das System.

Es empfiehlt sich daher, die Fehler auf verschiedenen Ebenen zu behandeln. Auf höchster Ebene können Sie den Fehler beispielsweise behandeln, indem Sie nur den tatsächlichen Fehler protokollieren und dem Benutzer eine einfache und benutzerfreundliche Meldung anzeigen.


0

Ja, der Operator zur Fehlerunterdrückung ist im Allgemeinen eine schlechte Idee.

Sie sollten die Fehlerberichterstattung in der Konfiguration ( php.ini) verwalten. So können Sie für jede Umgebung eine andere Einstellung wählen (z. B. Warnungen in der Entwicklung belassen und in der Produktion ausblenden).

Die einzige Situation, in der die Verwendung @sinnvoll sein könnte, besteht darin, eine Bibliothek für andere Entwickler zu entwickeln. Wenn Sie sich freiwillig dafür entscheiden, etwas zu tun, das eine Warnung erzeugt, und die Benutzer Ihrer Bibliothek nicht mit einer Warnung belästigen möchten, die nicht von ihnen abhängt, @könnte dies eine Lösung sein.

Ich kann mir keine andere Verwendung vorstellen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.