Warum enthalten viele Ausnahmemeldungen keine nützlichen Details?

220

Es scheint eine gewisse Übereinstimmung zu bestehen, dass Ausnahmemeldungen nützliche Details enthalten sollten .

Warum enthalten viele häufige Ausnahmen von Systemkomponenten keine nützlichen Details?

Einige Beispiele:

  • Der .NET- ListIndexzugriff ArgumentOutOfRangeExceptiongibt weder den Indexwert an, der versucht wurde und ungültig war, noch den zulässigen Bereich.
  • Grundsätzlich sind alle Ausnahmenachrichten aus der MSVC C ++ - Standardbibliothek völlig unbrauchbar (in der gleichen Weise wie oben).
  • Oracle-Ausnahmen in .NET, die Ihnen (umschrieben) mitteilen, dass "TABLE OR VIEW not found" (Tabelle oder Ansicht nicht gefunden), aber nicht welche .

Aus diesem Grund scheint es mir, dass Ausnahmemeldungen zum größten Teil nicht genügend Details enthalten, um nützlich zu sein. Entsprechen meine Erwartungen nicht den Erwartungen? Benutze ich Ausnahmen falsch, dass ich das überhaupt bemerke? Oder vielleicht mein Eindruck ist falsch: eine Mehrheit von Ausnahmen Sie bieten tatsächlich nützliche Details?

Martin Ba
quelle
59
Es sollte beachtet werden, dass von Seiten der Sicherheitsexperten "Fehlermeldungen sollten keine Details zu den Interna des Systems enthalten" eine Faustregel ist.
Telastyn
118
@Telastyn: Nur wenn Ihr System für Angreifer offen ist. Wenn Sie zum Beispiel einen Webserver betreiben, möchten Sie dem Endbenutzer langweilige Fehlermeldungen übermitteln, aber dennoch möchten Sie, dass sehr detaillierte Fehlermeldungen an Ihrem Ende protokolliert werden. Und bei clientseitiger Software, bei der der Benutzer kein Angreifer ist, möchten Sie auf jeden Fall, dass diese Fehlermeldungen so detailliert wie möglich sind. Wenn also etwas schief geht und Sie einen Fehlerbericht erhalten, können Sie mit so vielen Informationen arbeiten wie möglich, denn oft ist das alles, was Sie bekommen.
Mason Wheeler
9
@Snowman: Was ist für den Benutzer unzugänglich, wenn es sich um clientseitige Software handelt? Der Besitzer der Maschine besitzt die Maschine und kann auf alles zugreifen.
Mason Wheeler
6
Es gibt immer einige zusätzliche Informationen, die Sie gerne hätten. Ich finde die Botschaften, die Sie als Beispiele geben, ziemlich gut. Sie können das Problem mit ihnen debuggen. Weitaus besser als "Fehler 0x80001234" (Beispiel inspiriert von Windows Update).
USR

Antworten:

204

Ausnahmen enthalten keine nützlichen Details, da das Konzept der Ausnahmen in der Softwareentwicklungsdisziplin noch nicht ausreichend ausgereift ist, so dass viele Programmierer sie nicht vollständig verstehen und sie daher nicht richtig behandeln.

Ja, IndexOutOfRangeExceptionsollte den genauen Index enthalten, der außerhalb des gültigen Bereichs lag, sowie den Bereich, der zum Zeitpunkt des Auslösens gültig war, und ist für die Ersteller der .NET-Laufzeit verächtlich, sofern dies nicht der Fall ist. Ja, die table or view not foundAusnahme von Oracle sollte den Namen der Tabelle oder Sicht enthalten, die nicht gefunden wurde, und auch die Tatsache, dass sie für den Verantwortlichen nicht verächtlich ist.

Zu einem großen Teil rührt die Verwirrung von der fehlgeleiteten ursprünglichen Idee her, dass Ausnahmen von Menschen lesbare Botschaften enthalten sollten, was wiederum darauf zurückzuführen ist, dass man nicht weiß, worum es sich bei Ausnahmen handelt. Es handelt sich also um einen Teufelskreis.

Da die Menschen der Meinung sind, dass die Ausnahme eine für Menschen lesbare Nachricht enthalten sollte, sind sie der Ansicht, dass die von der Ausnahme übermittelten Informationen auch in der für Menschen lesbaren Nachricht formatiert werden sollten. Dann ist es ihnen entweder langweilig, alle für Menschen lesbaren Nachrichten zu schreiben. oder sie befürchten, dass dadurch eine nicht zu empfehlende Menge an Informationen an neugierige Augen weitergegeben wird, die die Nachricht möglicherweise sehen. (Die in anderen Antworten genannten Sicherheitsprobleme.)

Die Wahrheit ist jedoch, dass sie sich darüber keine Sorgen machen sollten, da die Ausnahme keine für Menschen lesbare Botschaft enthalten sollte. Ausnahmen sind Dinge, die nur Programmierer jemals sehen und / oder behandeln sollten. Wenn es jemals notwendig sein sollte, einem Benutzer Fehlerinformationen zu präsentieren, muss dies auf sehr hohem Niveau, auf raffinierte Weise und in der Sprache des Benutzers erfolgen, die statistisch gesehen wahrscheinlich nicht Englisch ist.

Für uns Programmierer ist die "Nachricht" der Ausnahme der Klassenname der Ausnahme , und alle anderen Informationen, die für die Ausnahme relevant sind, sollten in (endgültige / schreibgeschützte) Mitgliedsvariablen des Ausnahmeobjekts kopiert werden. Am liebsten ist jedes einzelne denkbare bisschen davon. Auf diese Weise muss (oder sollte) keine Nachricht generiert werden, und daher können keine neugierigen Augen sie sehen.

Um auf die Besorgnis einzugehen, die Thomas Owens in einem der folgenden Kommentare zum Ausdruck gebracht hat:

Ja, natürlich, auf einer bestimmten Ebene, Sie werden eine Log - Nachricht in Bezug auf die Ausnahme erstellen. Aber Sie sehen bereits das Problem mit dem, was Sie sagen: Einerseits ist eine Ausnahmeprotokollnachricht ohne Stapelablaufverfolgung nutzlos, andererseits möchten Sie dem Benutzer nicht die gesamte Ausnahme-Stapelablaufverfolgung anzeigen lassen. Auch hier besteht unser Problem darin, dass unsere Perspektive durch traditionelle Praktiken verzerrt wird. Protokolldateien wurden traditionell im Nur-Text-Format erstellt, was vielleicht in den Kinderschuhen unserer Disziplin in Ordnung war, aber vielleicht auch nicht mehr: Wenn Sicherheitsbedenken bestehen, muss die Protokolldatei binär und / oder verschlüsselt sein.

Unabhängig davon, ob es sich um Binär- oder Nur-Text-Dateien handelt, sollte die Protokolldatei als Stream betrachtet werden, in den die Anwendung die Debuginformationen serialisiert. Ein solcher Stream ist nur für die Augen des Programmierers bestimmt, und das Generieren von Debugging-Informationen für eine Ausnahme sollte so einfach wie das Serialisieren der Ausnahme in den Debug-Protokoll-Stream sein. Auf diese Weise sehen Sie im Protokoll den Namen der Ausnahmeklasse (der, wie ich bereits ausgeführt habe, für alle praktischen Zwecke "die Nachricht" ist). und praktisch, um in ein Protokoll aufzunehmen, und die gesamte Stapelverfolgung. Beachten Sie, dass die Formatierung einer für Menschen lesbaren Ausnahmemeldung in diesem Prozess auffällig fehlt .

PS

Ein paar meiner Gedanken zu diesem Thema finden Sie in dieser Antwort: Wie schreibe ich eine gute Ausnahmebedingungsnachricht?

PPS

Es scheint, dass viele Leute von meinem Vorschlag zu binären Protokolldateien abgehakt wurden, deshalb habe ich die Antwort noch einmal geändert, um noch klarer zu machen, dass ich hier nicht vorschlage, dass die Protokolldatei binär sein soll, sondern dass Die Protokolldatei kann bei Bedarf binär sein.

Mike Nakis
quelle
4
Ich habe einige der Ausnahmeklassen in .NET Framework durchgesehen, und es hat sich herausgestellt, dass es zahlreiche Möglichkeiten gibt, diese Art von Informationen programmgesteuert hinzuzufügen. Ich schätze, die Frage lautet: Warum nicht? Aber +1 für die ganze "lesbare" Sache.
Robert Harvey
7
Ich bin nicht einverstanden, dass Ausnahmen keine von Menschen lesbare Komponente enthalten sollten. Auf einer bestimmten Ebene möchten Sie möglicherweise eine Protokollmeldung zu der Ausnahme erstellen. Ich würde argumentieren, dass das Protokollieren eines Stack-Traces in einer benutzerlesbaren Protokolldatei Implementierungsdetails enthält, die Sie nicht verfügbar machen möchten. Daher sollte die für den Menschen lesbare Nachricht protokolliert werden. Wenn Entwicklern die Protokolldatei mit dem Fehler angezeigt wird, sollten sie über einen Ausgangspunkt verfügen, an dem sie mit dem Debuggen beginnen und die Ausnahmebedingung erzwingen können. Die für den Menschen lesbare Komponente sollte angemessen detailliert sein, ohne die Implementierung preiszugeben.
Thomas Owens
44
Also sind Programmierer keine Menschen? Ein Blick auf meine Kollegen bestätigt einige Vermutungen, die ich seit einiger Zeit hatte ...
gbjbaanb
51
Auch hier ist nichts falsch daran, den Benutzer den gesamten Stack-Trace anzeigen zu lassen , solange die Software clientseitig ist. Jedes professionelle Softwareprojekt, an dem ich je gearbeitet habe, und die meisten Amateurprojekte, enthielten ein Protokollierungssystem, das einen vollständigen Fehlerauszug generierte, wenn eine nicht behandelte Ausnahme ausgelöst wurde, einschließlich der vollständigen Stapelspuren aller derzeit ausgeführten Threads in der Prozess. Und der Benutzer kann es sich jederzeit ansehen (keuchen, oh Horror!), Da dies notwendig (nicht nur nützlich, sondern erforderlich ) ist, um die Fehlermeldung an uns zurückzusenden! Was stimmt damit nicht?
Mason Wheeler
13
Ich bin auch in Bezug auf reine Binär- Protokolldateien nicht überzeugt . Hauptsächlich wegen meiner Erfahrung mit systemd. Sein spezielles Werkzeug zum Anzeigen dieser Protokolle ist ziemlich verwirrend und scheint von einem Komitee von Shakespeares Affen entworfen worden zu sein. Bedenken Sie, dass in einer Webanwendung häufig der Systemadministrator als erster Ihre Ausnahme sieht und er feststellen möchte, ob eine Korrektur erforderlich ist (z. B. wenn auf der Festplatte nicht genügend Speicherplatz vorhanden ist) oder ob eine Rückgabe erforderlich ist an die Entwickler.
Michael Hampton
46

Warum enthalten viele häufige Ausnahmen von Systemkomponenten keine nützlichen Details?

Nach meiner Erfahrung gibt es eine Reihe von Gründen, aus denen Ausnahmen keine nützlichen Informationen enthalten. Ich gehe davon aus, dass diese Gründe auch für Systemkomponenten gelten - aber ich weiß es nicht genau.

  • Sicherheitsorientierte Personen sehen Ausnahmen als Ursache für Informationslecks (zum Beispiel ). Da das Standardverhalten von Ausnahmen darin besteht, diese Informationen dem Benutzer anzuzeigen, sind Programmierer manchmal vorsichtig.
  • In C ++ habe ich Argumente gegen die Zuweisung von Speicher in Catch-Blöcken gehört (in denen zumindest ein Teil des Kontexts für gute Nachrichten liegt). Diese Zuweisung ist schwer zu verwalten und kann, was noch schlimmer ist, zu einer Ausnahmebedingung wegen unzureichendem Arbeitsspeicher führen. Es ist schwierig, Ausnahmen gut zu formatieren, ohne Speicher zuzuweisen, und diese Vorgehensweise ist möglicherweise wie die von Programmierern zwischen den Sprachen gewechselt.
  • Sie wissen es nicht. Ich meine, es gibt Szenarien, in denen der Code keine Ahnung hat, was schief gelaufen ist. Wenn der Code es nicht weiß, kann er es Ihnen nicht sagen.
  • Ich habe an Orten gearbeitet, an denen Lokalisierungsbedenken verhinderten, dass nur englische Zeichenfolgen in das System eingefügt wurden - selbst mit Ausnahme von Ausnahmen, die nur von englischsprachigen Supportmitarbeitern gelesen wurden.
  • An einigen Stellen habe ich Ausnahmen gesehen, die eher wie Asserts verwendet wurden. Sie sind da, um während der Entwicklung eine klare, laute Botschaft zu übermitteln, dass etwas nicht getan wurde oder an einem Ort eine Änderung vorgenommen wurde, an einem anderen jedoch nicht. Diese sind oftmals so einzigartig, dass eine gute Nachricht doppelt oder einfach verwirrend wäre.
  • Die Leute sind faul, Programmierer mehr als die meisten anderen. Wir verbringen viel weniger Zeit auf dem außergewöhnlichen Weg als auf dem glücklichen Weg, und dies ist ein Nebeneffekt.

Entsprechen meine Erwartungen nicht den Erwartungen? Benutze ich Ausnahmen falsch, dass ich das überhaupt bemerke?

Irgendwie? Ich meine, Ausnahmen sollten nette Nachrichten haben, aber sie sind auch Ausnahmen . Sie sollten Ihre Zeit damit verbringen, Code zu entwerfen, um außergewöhnliche Bedingungen zu vermeiden, oder Code zu schreiben, um außergewöhnliche Bedingungen zu behandeln (die Nachricht zu ignorieren), und sie nicht als eine Art interaktiven Feedback-Mechanismus beim Codieren verwenden. Es ist unvermeidlich, sie für Debugging-Zwecke zu verwenden, aber in den meisten Situationen sollte dies auf ein Minimum beschränkt werden. Dass Sie dieses Problem bemerken, macht mir Sorgen, dass Sie nicht gut genug daran arbeiten, es zu verhindern.

Telastyn
quelle
Ich bin mir bewusst, dass dies als C markiert wurde, aber ich sollte hinzufügen, dass Ihr letzter Absatz nicht für alle Sprachen gilt, da sich einige (zu Recht oder zu Unrecht) stark auf ausnahmebasierte Fehlerbehandlung und Berichterstellung verlassen können.
Lilienthal
1
@Lilienthal - wie? Keine mir vertraute Sprache macht so etwas regelmäßig.
Telastyn,
1
Ich denke, diese Antwort hat viele gute Inhalte, aber sie vermeidet es, das Fazit zu ziehen: "Sie sollten".
Djechlin
3
Vielen Dank. Ihre Sorge ist unbegründet (hoffe ich :-). Aber jedes Mal, wenn ich eine zusätzliche Minute damit verbringe aufzuspüren, was in diesem Unit Test schief gelaufen ist oder zusätzliche Zeit damit verbringe, Code zu analysieren, weil die Logdatei keine Informationen enthält, ärgere ich mich ein wenig über das vermeidbare Unwohlsein einiger Nachrichten :-)
Martin Ba
Das proprietäre ABAP von @Telastyn SAP verfügt über ein Ausnahmeklassenkonstrukt, das eine Nachricht enthalten kann. Hierbei handelt es sich im Wesentlichen um ein Objekt, das dem Benutzer den Programmstatus (Erfolg, Misserfolg, Warnung) zusammen mit einer dynamischen (mehrsprachigen) Nachricht mitteilen soll. Ich gebe zu, ich weiß nicht, wie weit verbreitet diese Art von Dingen ist oder ob sie in den Sprachen sogar gefördert werden, wenn es möglich ist, aber es gibt mindestens eine, in der es (bedauerlicherweise) üblich ist.
Lilienthal
12

Ich habe nicht viel Erfahrung mit C # oder C ++, aber ich kann Ihnen das sagen - von Entwicklern geschriebene Ausnahmen 9 von 10 sind nützlicher als jede generische Ausnahme, die Sie jemals finden werden.

Im Idealfall zeigt eine generische Ausnahme genau an, warum der Fehler aufgetreten ist, und Sie können ihn problemlos beheben - realistisch gesehen jedoch in großen Anwendungen mit mehreren Klassen, die eine Vielzahl verschiedener Arten von Ausnahmen auslösen können gleiche Art von Ausnahmen abgesehen, ist es immer wertvoller Ihren eigenen Ausgang für Fehler Rückkehr zu schreiben , als es auf der Standard - Nachricht verlassen ist.

Dies ist , wie es sein sollte, weil so viele Leute haben darauf hingewiesen, einige Anwendungen nicht wollen eine Fehlermeldung werfen , dass sie nicht sehen , der Benutzer möchte, aus Sicherheitsgründen oder zu vermeiden , dass sie verwirrend.

Stattdessen sollten Sie in Ihrem Entwurf vorhersehen, welche Arten von Fehlern in Ihrer Anwendung auftreten können (und es treten immer Fehler auf), und Fehlermeldungen verfassen, die Sie bei der Identifizierung des Problems unterstützen.

Dies wird Ihnen nicht immer weiterhelfen, da Sie nicht immer vorhersehen können, welche Fehlermeldung nützlich sein wird. Es ist jedoch der erste Schritt, um Ihre eigene Anwendung langfristig besser zu verstehen.

Zibbobz
quelle
7

Die Frage ist insbesondere, warum so viele von "Systemkomponenten" (auch als Standardbibliotheksklassen bezeichnet) ausgelöste Ausnahmen keine nützlichen Details enthalten.

Leider schreiben die meisten Entwickler weder die Kernkomponenten in Standardbibliotheken, noch werden detaillierte Konstruktionsdokumente oder andere Konstruktionsgründe notwendigerweise veröffentlicht. Mit anderen Worten, wir werden es vielleicht nie genau wissen.

Es gibt jedoch zwei wichtige Punkte, die beachtet werden müssen, warum detaillierte Ausnahmeinformationen möglicherweise nicht wünschenswert oder wichtig sind:

  1. Eine Ausnahme kann auf irgendeine Weise durch Aufrufen von Code verwendet werden: Eine Standardbibliothek kann die Verwendung der Ausnahme nicht einschränken. Insbesondere kann es dem Benutzer angezeigt werden. Betrachten Sie einen Array-Index außerhalb der Grenzen: Dies kann einem Angreifer nützliche Informationen liefern. Der Sprachdesigner hat keine Ahnung, wie eine Anwendung die ausgelöste Ausnahme verwendet oder welche Art von Anwendung sie ist (z. B. Web-App oder Desktop). Aus Sicherheitsgründen kann das Auslassen von Informationen daher sicherer sein.

  2. Ausnahmen sollten dem Benutzer nicht angezeigt werden. Zeigen Sie stattdessen eine angezeigte Fehlermeldung an und protokollieren Sie die Ausnahme an einem Ort, auf den ein Angreifer keinen Zugriff hat (falls zutreffend). Sobald der Fehler erkannt wurde, sollte ein Entwickler den Code debuggen und Stack-Frames und logische Pfade untersuchen. Zu diesem Zeitpunkt verfügt der Entwickler über mehr Informationen, als eine Ausnahme jemals erhoffen könnte.


quelle
3
1. Anhand dieser Kriterien erscheint es relativ willkürlich, welche Informationen ("Index außerhalb des Bereichs", Stack-Trace) und welche nicht (Indexwert) angezeigt werden. 2. Das Debuggen kann möglicherweise viel schneller und einfacher sein, wenn relevante dynamische Werte bekannt sind. Beispielsweise wird häufig sofort angezeigt, ob das Problem
Ben Aaronson,
@BenAaronson Die Identität / Klasse der Ausnahme gibt Auskunft über die Art des Fehlers. Mein Punkt ist, die Details könnten aus Sicherheitsgründen weggelassen werden (dh welcher bestimmte Wert den Fehler verursacht hat). Dieser Wert kann möglicherweise auf die Benutzereingabe zurückgeführt werden, sodass einem Angreifer Informationen angezeigt werden.
@Snowman Ich denke kaum, dass Sicherheit eine Überlegung ist, wenn ein vollständiger Stack-Trace verfügbar ist, und die Indexnummer nicht. Klar, ich verstehe einen Angreifer, der nach Pufferüberläufen sucht, aber viele Ausnahmen lassen auch ziemlich sichere Daten aus (z. B. welche Oracle-Tabelle nicht gefunden wurde)
gbjbaanb
@ gbjbaanb wer sagt, dass wir dem Benutzer den vollständigen Stack-Trace zeigen müssen?
1
Vielen Dank für diesen Einblick. Persönlich stimme ich nicht zu und denke, dass das Sicherheitsargument ein völliger Irrtum ist, aber es kann eine Begründung sein.
Martin Ba
4

Lassen Sie mich zunächst eine Blase platzen, indem ich sage, auch wenn die diag-Nachricht mit Informationen geladen ist, die Sie in 4 Sekunden zur genauen Codezeile und zum Unterbefehl führen. Es besteht die Möglichkeit, dass die Benutzer sie niemals aufschreiben oder an den Support weiterleiten und dir wird gesagt "Nun, es hat etwas über einen Verstoß gesagt ... ich weiß nicht, dass es kompliziert aussah!"

Ich schreibe seit mehr als 30 Jahren Software und unterstütze die Ergebnisse anderer Software. Persönlich hat die aktuelle Qualität einer Ausnahmebedingungsnachricht praktisch nichts mit Sicherheit zu tun, unabhängig davon, wie die Endergebnisse ihrem Modell entsprachen Das Universum, viel mehr mit der Tatsache zu tun, dass so viele in unserer Branche ursprünglich Autodidakten waren und nie Unterricht in Kommunikation beinhalteten. Wenn wir alle neuen Programmierer für ein paar Jahre in eine Wartungsposition zwingen würden, in der sie herausfinden müssten, was schief gelaufen ist, würden sie vielleicht verstehen, wie wichtig zumindest eine Form von Präzision ist.

Kürzlich wurde in einer Anwendung, die neu erstellt wurde, entschieden, dass Rückkehrcodes in eine von drei Gruppen fallen:

  • 0 bis 9 wären Erfolg durch Erfolg mit zusätzlichen Informationen.
  • 10 bis 99 wären nicht schwerwiegende (behebbare) Fehler, und
  • 101 bis 255 wären schwerwiegende Fehler.

(100 wurden aus irgendeinem Grund ausgelassen)

In einem bestimmten Workflow wurde unser Gedanke wiederverwendet, oder generischer Code würde generische Rückgaben (> 199) für schwerwiegende Fehler verwenden, sodass 100 schwerwiegende Fehler für einen Workflow möglich sind. Bei geringfügig differenzierenden Daten in der Nachricht können Fehler, z. B. nicht gefundene Dateien, denselben Code verwenden und sich von den Nachrichten unterscheiden.

Als der Code von den Vertragspartnern zurückkam, konnten Sie unsere Überraschung nicht glauben, als praktisch JEDER EINZELNE FATALE FEHLER der Rückkehrcode 101 war.

Alles, was ich in Betracht gezogen habe, ist, dass die Antwort auf Ihre Frage so bedeutungslos ist, weil sie bei der ursprünglichen Erstellung Platzhalter sein sollten, auf die niemand zurückkam. Irgendwann fanden die Leute heraus, wie man Probleme nicht aufgrund der Nachrichten behebt, sondern ABWEICHEN kann.

Seit dieser Zeit hatten die Autodidakten einfach nie ein gutes Beispiel dafür, was eine Ausnahme enthalten sollte. Hinzu kommt, dass mehr Benutzer die Nachrichten nicht lesen und erst recht nicht versuchen, sie an den Support weiterzuleiten (ich habe Fehlermeldungen gesehen, die von den Verwendeten ausgeschnitten und eingefügt wurden, die dann redigiert wurden, bevor sie mit dem späteren Kommentar an den Support weitergeleitet wurden schien eine Menge Informationen zu sein und ich konnte unmöglich alles wollen, also entfernten sie zufällig einen Haufen davon.

Und seien wir ehrlich, mit viel zu vielen (nicht allen, aber viel zu vielen) Codierern der nächsten Generation, wenn es mehr Arbeit ist und keinen Flash hinzufügt, es einfach nicht wert

Letzter Hinweis: Wenn eine Fehlermeldung einen Fehler- / Rückgabecode enthält, sollte sich in den ausgeführten Modulen meines Erachtens eine Zeile befinden, die so etwas wie "if condition return code-value" und "condition" enthält und Ihnen den Grund für den Rückgabecode angibt aufgetreten. Dies scheint eine einfache logische Herangehensweise zu sein, aber für mein ganzes Leben ist es nur VERSUCHEN, Microsoft zu veranlassen, Ihnen mitzuteilen, was passiert ist, als ein Windows-Upgrade auf CODE 80241013 oder einem anderen sehr eindeutigen Bezeichner fehlgeschlagen ist. Ein bisschen traurig, nicht wahr?

Geil
quelle
8
"... Sie würden unsere Überraschung nicht glauben, wenn praktisch JEDER EINZIGE FATALE FEHLER der Rückkehrcode 101 war." Du hast recht. Ich würde nicht glauben, dass Sie überrascht waren, als der Auftragnehmer Ihren Anweisungen folgte.
Odalrick
3
chances are the users will never write it down... and you will be told "Well it said something about a violation..." Aus diesem Grund verwenden Sie ein Tool zur Protokollierung von Ausnahmen, um automatisch den Fehlerbericht mit dem Stack-Trace zu erstellen und möglicherweise sogar an Ihren Server zu senden. Ich hatte einmal einen Benutzer, der nicht sehr technisch war. Jedes Mal, wenn sie eine Nachricht vom Fehlerprotokollierer übermittelte, lautete die Meldung "Ich bin nicht sicher, was ich falsch gemacht habe, aber ...", egal wie oft ich erklärte, dass dieser Fehler bedeutete, dass der Fehler auf meiner Seite war . Aber ich habe immer die Fehlermeldungen von ihr bekommen!
Mason Wheeler
3

Ich stimme zwar zu, dass Ausnahmen so viele Informationen wie möglich enthalten oder zumindest weniger allgemein sein sollten. In dem Fall, dass die Tabelle nicht gefunden wird, wäre der Tabellenname nett.

Sie wissen jedoch mehr darüber, was Sie an der Stelle im Code versucht haben, an der Sie die Ausnahme erhalten haben. Während Sie häufig nicht viel tun können, um die Situation zu korrigieren, wenn in einer Bibliothek außerhalb Ihrer Kontrolle etwas schief geht, können Sie viel nützlichere Informationen hinzufügen, in welcher Situation etwas schief gegangen ist.

Im Fall einer nicht gefundenen Tabelle hilft es Ihnen nicht viel, wenn Sie erfahren, dass die nicht gefundene Tabelle STUDENTS heißt, weil Sie keine solche Tabelle haben und diese Zeichenfolge nicht in Ihrem Code enthalten ist.

Aber wenn Sie die Ausnahme abfangen und sie mit der SQL-Anweisung erneut auslösen, die Sie ausführen wollten, ist es besser, wenn Sie versuchen, einen Datensatz einzufügen, dessen Namensfeld Robert ist '); TROPFENTISCHSTUDENTEN; (Es gibt immer eine xkcd!)

Um den weniger informativen Ausnahmen entgegenzuwirken: Try-Catch-Rethrow mit mehr Informationen, die spezifisch für das sind, was Sie versucht haben.

Ich sollte wahrscheinlich hinzufügen, dass dies eher eine Antwort auf das Warum in der Frage ist, dass ein wahrscheinlicher Grund, warum der Fokus der Hersteller der Bibliotheken nicht darauf lag, die Ausnahmebotschaften zu verbessern, darin besteht, dass sie es nicht wissen warum etwas versucht wurde, das fehlgeschlagen ist, ist diese Logik im aufrufenden Code.

Gebogen
quelle
zB in C ++ sollten Sie throw_with_nestedviel verwenden.
Miles Rout
3

Um eine etwas andere Antwort zu geben: Der fehlerhafte Code wurde wahrscheinlich nach folgenden Kriterien erstellt:

  • Die Funktion empfängt X und gibt Y zurück
  • Wenn X ungültig ist, wird die Ausnahme Z ausgelöst

Fügen Sie den Druck hinzu, in kürzester Zeit und mit minimalem Aufwand exakt die Spezifikationen zu liefern (aus Angst, bei Überprüfungen / Tests abgelehnt zu werden). Dann haben Sie Ihr Rezept für eine vollständig konforme und nicht hilfreiche Bibliotheksausnahme.

Stu Pegg
quelle
3

Ausnahmen verursachen sprach- und implementierungsspezifische Kosten.

Zum Beispiel sind C ++ - Ausnahmen erforderlich, um alle lebenden Daten zwischen dem Auslösen eines Anrufrahmens und dem Abfangen eines Anrufrahmens zu zerstören, und das ist teuer. Daher möchten Programmierer Ausnahmen nicht häufig verwenden.

In Ocaml ist das Auslösen von Ausnahmen fast so schnell wie ein C setjmp(seine Kosten hängen nicht von der Anzahl der durchquerten Anrufrahmen ab), sodass Entwickler viel davon verwenden können (selbst in nicht außergewöhnlichen, sehr häufigen Fällen). Im Gegensatz dazu sind C ++ - Ausnahmen stark genug, sodass Sie sie wahrscheinlich nicht so häufig verwenden wie in Ocaml.

Ein typisches Beispiel ist eine rekursive Suche oder Erforschung, die in einer ziemlich tiefen Rekursion "gestoppt" werden kann (z. B. ein Blatt in einem Baum finden oder eine Vereinigungsfunktion). In einigen Sprachen ist es schneller (also idiomatischer), diese Bedingung an jeden Anrufer weiterzugeben. In anderen Sprachen ist das Auslösen einer Ausnahme schneller.

In Abhängigkeit von der Sprache (und den Gewohnheiten der Entwickler, die sie verwenden) kann eine Ausnahme viele nützliche Details enthalten oder im Gegenteil als schneller nicht-lokaler Sprung verwendet werden und nur die sehr nützlichen Daten enthalten.

Basile Starynkevitch
quelle
6
"Zum Beispiel sind C ++ - Ausnahmen erforderlich, um alle lebenden Daten zwischen dem Auslösen eines Aufrufrahmens und dem Abfangen eines Aufrufrahmens zu zerstören, und das ist teuer. Daher möchten Programmierer Ausnahmen nicht häufig verwenden." Total Mist. Die Hauptstärke von C ++ - Ausnahmen besteht darin, dass Destruktoren deterministisch aufgerufen werden. Niemand würde sie benutzen, wenn sie nur springen würden.
Miles Rout
Ich weiß das, aber es ist eine Tatsache, dass C ++ - Ausnahmen nicht wie Ocaml sind und Sie sie nicht wie in Ocaml verwenden.
Basile Starynkevitch
5
Sie verwenden C ++ - Ausnahmen nicht für den Steuerungsfluss in C ++, da dies den Code unleserlich und schwer verständlich macht.
Miles Rout
-2

Aus welchem ​​Grund halten Sie den Indexwert oder den erforderlichen Bereich oder den Namen der Tabelle für ein nützliches Detail, abgesehen von einer Ausnahme?

Ausnahmen sind keine Fehlerbehandlungsmechanismen. Sie sind ein Wiederherstellungsmechanismus .

Der Punkt der Ausnahmen besteht darin, die Codeebene zu erreichen, die die Ausnahme behandeln kann. Überall dort, wo sich diese Ebene befindet, verfügen Sie entweder über die erforderlichen Informationen oder sie sind nicht relevant. Wenn Sie Informationen benötigen, aber keinen unmittelbaren Zugriff darauf haben, behandeln Sie die Ausnahme nicht auf der entsprechenden Ebene.

Ich kann mir nur einmal überlegen, wo zusätzliche Informationen hilfreich sein könnten , und zwar auf der absoluten obersten Ebene Ihrer Anwendung, in der Sie abstürzen und einen Fehlerbericht ausgeben. Es ist jedoch nicht die Aufgabe der Ausnahme, auf diese Informationen zuzugreifen, sie zu kompilieren und zu speichern.

Ich sage nicht, dass Sie einfach überall "werfen neue Ausnahme" und nennen es gut, es ist möglich, schlechte Ausnahmen zu schreiben. Das Einfügen irrelevanter Informationen ist jedoch nicht erforderlich, um sie ordnungsgemäß zu verwenden.

Odalrick
quelle
Ich würde den Namen der fehlenden Datenbanktabelle nicht als irrelevant bezeichnen, obwohl ich den von Ihnen angesprochenen Punkt verstehe und mit ihm sympathisiere. Ich habe dir eine Gegenstimme gegeben.
Daniel Hollinrake
1
@DanielHollinrake Ja, der Tabellenname ist definitiv der am wenigsten irrelevante der Beispiele. In dem Code, mit dem ich arbeite, ist diese Art von Problem bedrückend häufig, und wenn man sich ansieht, wie der Tabellenname entstellt wurde, kann man feststellen, was nicht stimmt. Ich habe versucht, ein Beispiel zu finden, warum diese Dinge für die Ausnahme irrelevant sind. Vielleicht kann ich das verwenden ...
Odalrick
Ich stimme dir nicht zu. Für die Behandlung einer Ausnahme sind möglicherweise keine zusätzlichen Details erforderlich, da Sie die Anwendung nur vor einem Absturz schützen möchten. Schließlich müssen Sie jedoch feststellen, warum sie nicht funktioniert hat, und sie muss behoben werden. Wenn Sie außer dem Ausnahmetyp keine Hinweise haben, sehen Sie beim Debuggen gut aus.
t3chb0t
@ t3chb0t Dafür ist der Stack-Trace und die Klasse der Ausnahme und des Speicherauszugs und alles andere bestimmt. Wie würde es Ihnen helfen , wenn ein Kunde anruft und sagt "Der Computer teilt mir mit, dass er versucht hat, auf den Index 5 zuzugreifen, und dieser nicht vorhanden ist." Es könnte nur helfen, wenn Sie auch die Liste, den Kontext für die Liste und alles andere, was nützlich sein könnte, serialisieren. Sie sollten nicht bei jedem Auslösen einer Ausnahme den gesamten Status der Anwendung serialisieren.
Odalrick,
@Odalrick für den Kunden hat vielleicht keine Bedeutung, aber als Entwickler schätze ich alle Informationen, die ich bekommen kann ;-) Dann vielleicht ein anderes Beispiel: Sagen wir, es tritt eine SqlExeption auf und das ist alles, was Sie wissen ... Es ist viel einfacher, sie zu reparieren Wenn Sie wissen, welche Verbindungszeichenfolge oder Datenbank oder Tabelle usw. nicht funktioniert hat, ist dies umso wichtiger, wenn Ihre Anwendung mehrere Datenbanken verwendet. Für einen detaillierten Stack-Trace müssen pdb-Dateien mit der Anwendung ausgeliefert werden. Dies ist nicht immer möglich. Auch Speicherabbilder können sehr groß werden und können nicht immer übertragen werden.
t3chb0t