Implementieren der Fehlerbehandlung [geschlossen]

13

Obwohl ich einige Jahre professionell programmiert habe, verstehe ich die Fehlerbehandlung immer noch nicht vollständig. Obwohl meine Anwendungen einwandfrei funktionieren, wird die Fehlerbehandlung nicht professionell implementiert und ist eine Mischung aus einer Reihe von Techniken.

Es gibt keine Struktur hinter meiner Fehlerbehandlung. Ich möchte lernen und verstehen, wie es auf professioneller Ebene umgesetzt wird. Dies ist ein Bereich, in dem mir Kenntnisse fehlen.

Wann sollte ich Ausnahmen verwenden und wann sollte ich einen Erfolgsstatus zurückgeben, der im Logikfluss überprüft werden soll? Ist es in Ordnung, eine Ausnahme zu mischen und einen Status zurückzugeben?

Ich codiere hauptsächlich in C #.

James Jeffery
quelle
2
Warum abstimmen? Ich stelle eine ernsthafte Frage zur Implementierung der Fehlerbehandlung und zur Vorgehensweise. Wenn dies nicht der beste Ort ist, um Programmierern eine solche Frage zu stellen, wo ist sie dann? Es nervt mich wirklich, wenn Leute solche Fragen ablehnen, weil es nirgendwo anders eine solche Frage gibt. Es ist möglicherweise der einzige Ort im Internet, an dem ich eine zuverlässige Antwort und mögliche Ressourcen erhalte. Anstatt also eine Frage abzustimmen, die andere sicherlich von Google beantworten würden, wäre es nicht einfacher, sie zu beantworten?
James Jeffery
6
Ihre Frage ist sehr weit gefasst. Vielleicht können Sie den Umfang einschränken, indem Sie bestimmte Beispiele dafür anführen, wie Sie Ihre Codierungsziele nicht erreicht haben.
Andyz Smith
Es gibt viele Artikel im Internet über die Fehlerbehandlung: Versuchen Sie Folgendes
Nir Kornfeld

Antworten:

25
  1. Verwenden Sie Ausnahmen für außergewöhnliche Dinge, Dinge, von denen Sie nicht erwarten können, dass sie zu oft auftreten. Dinge, die darauf hinweisen, dass etwas schief geht. Wenn beispielsweise das Netzwerk ausfällt, ist dies eine Ausnahme für einen Webserver. Wenn die Datenbank nicht verfügbar ist, bedeutet dies, dass etwas nicht stimmt. Wenn die Konfigurationsdatei fehlt, bedeutet dies wahrscheinlich, dass der Benutzer damit einen Fehler gemacht hat.

  2. Verwenden Sie keine Ausnahmen, um mit falschem Code umzugehen. Um die Richtigkeit des Codes zu überprüfen, sollten Sie entweder die Zusicherungen oder in .NET Framework 4 und höher Codeverträge verwenden (die Zusicherungen ersetzen und zusätzliche, besonders nützliche Funktionen aufweisen).

  3. Verwenden Sie Ausnahmen nicht in Ausnahmefällen. Die Tatsache, dass der Benutzer, wenn er aufgefordert wird, eine Nummer einzugeben, "Hund" eingibt, ist keine Ausnahme, die eine Ausnahme verdient.

  4. Seien Sie vorsichtig bei der Auswahl der Ausnahmetypen. Erstellen Sie bei Bedarf Ihre eigenen Typen. Wählen Sie die Erbschaft sorgfältig aus und denken Sie daran, dass das Fangen von Eltern auch die Kinder fängt. Niemals throw Exception.

  5. Verwenden Sie keine Rückkehrcodes für Fehler. Fehlercodes können leicht ausgeblendet, ignoriert und vergessen werden. Wenn ein Fehler auftritt, können Sie ihn entweder behandeln oder an den oberen Stapel weitergeben.

  6. In Fällen, in denen erwartet wird, dass eine Methode einen Fehler zurückgibt und der Fehler nicht außergewöhnlich ist, verwenden Sie Aufzählungen, niemals Fehlernummern. Beispiel:

    // Note that the operation fails pretty often, since it deals with the servers which are
    // frequently unavailable, and the ones which send garbage instead of the actual data.
    private LoadOperationResult LoadProductsFromWeb()
    {
        ...
    }

    Die Bedeutung von LoadOperationResult.ServerUnavailable, LoadOperationResult.ParsingErrorusw. ist viel deutlicher, als sich beispielsweise daran zu erinnern, dass Code 12 bedeutet, dass der Server heruntergefahren ist, und Code 13 - dass die Daten nicht analysiert werden können.

  7. Verwenden Sie Fehlercodes, wenn sie auf die allgemeinen Codes verweisen, die jedem Entwickler in der jeweiligen Domäne bekannt sind. Erfinden Sie beispielsweise keinen Enum-Wert für HTTP 404 Not Found oder HTTP 500 Internal Server Error neu.

  8. Hüten Sie sich vor Booleschen. Früher oder später möchten Sie nicht nur wissen, ob eine bestimmte Methode erfolgreich war oder nicht, sondern warum. Ausnahmen und Aufzählungen sind dafür viel mächtiger.

  9. Fangen Sie nicht jede Ausnahme ab (es sei denn, Sie befinden sich ganz oben auf dem Stapel). Wenn Sie eine Ausnahme abfangen, sollten Sie bereit sein, damit umzugehen. Das Abfangen von allem zeigt, dass es Ihnen egal ist, ob Ihr Code korrekt ausgeführt wird. Dies löst möglicherweise das Problem "Ich möchte jetzt nicht nach Lösungen suchen", kann Sie aber früher oder später verletzen.

  10. Werfen Sie in C # niemals Ausnahmen wie die folgenden erneut aus:

    catch (SomeException ex)
    {
        ...
        throw ex;
    }

    weil Sie den Stapel brechen. Tun Sie dies stattdessen:

    catch (SomeException)
    {
        ...
        throw;
    }
  11. Bemühen Sie sich, wenn Sie Ausnahmemeldungen schreiben. Wie oft habe ich sowas schon gesehen throw Exception("wrong data")oder throw Exception("shouldn't call this method in this context"). Andere Entwickler, darunter Sie sechs Monate später, hätten keine Ahnung, welche Daten falsch sind und warum oder warum wir eine Methode nicht in einem Kontext oder in welchem ​​Kontext genau aufrufen sollten.

  12. Dem Benutzer keine Ausnahmemeldungen anzeigen. Sie sind für normale Leute nicht zu erwarten und für Entwickler selbst oft sogar unlesbar.

  13. Lokalisieren Sie keine Ausnahmemeldungen. Das Durchsuchen der Dokumentation nach einer lokalisierten Nachricht ist anstrengend und sinnlos: Jede Nachricht sollte nur in Englisch und Englisch verfasst sein.

  14. Konzentrieren Sie sich nicht ausschließlich auf Ausnahmen und Fehler: Protokolle sind ebenfalls äußerst wichtig.

  15. Vergessen Sie in .NET nicht, Ausnahmen in die XML-Dokumentation der Methode aufzunehmen:

    /// <exception cref="MyException">Description of the exception</exception>

    Das Einbeziehen von Ausnahmen in die XML-Dokumentation erleichtert die Arbeit der Person, die die Bibliothek verwendet, erheblich. Es gibt nichts Ärgerlicheres, als zu erraten, welche Ausnahme möglicherweise von einer Methode ausgelöst werden könnte und warum.

    In diesem Sinne¹ bietet die Java-Ausnahmebehandlung einen strengeren und besseren Ansatz. Es zwingt Sie, entweder mit Ausnahmen umzugehen, die möglicherweise von den aufgerufenen Methoden ausgelöst werden, oder in Ihrer eigenen Methode zu deklarieren, dass die Ausnahmen ausgelöst werden können, die Sie nicht behandeln, wodurch die Dinge besonders transparent werden.


¹ Abgesehen davon finde ich die Unterscheidung zwischen Ausnahmen und Fehlern in Java ziemlich nutzlos und verwirrend, da die Sprache Ausnahmen aktiviert und deaktiviert hat. Glücklicherweise hat .NET Framework nur Ausnahmen und keine Fehler.

MainMa
quelle
Daraus habe ich ein bisschen Zitat gelernt. Darf ich fragen, wo die Liste herkommt? Ort oder persönliche Erfahrung? So oder so außergewöhnlicher Job (hehe bekommen es?).
Shelby115
@ Shelby115: Die Liste stammt aus der Reihenfolge: Stapelaustausch, persönliche Erfahrung und Code Complete von Steve Mcconnell.
Arseni Mourzenko
Vielen Dank @MainMa, das ist eine hervorragende Antwort! Ich hatte Code Complete, als ich an der Universität war, aber jemand hat es gestohlen. Ich konnte es nicht lesen.
James Jeffery
@JamesJeffery: dann die zweite Ausgabe in einer Bibliothek ausleihen oder eine kaufen: Es ist eines der seltenen entwicklungsbezogenen Bücher, die das Geld absolut wert sind.
Arseni Mourzenko
@MainMa Gerade bei Amazon bestellt, danke: DI besitzt auch Clean Code und hat Kapitel 7 komplett vergessen.
James Jeffery
1

Ich denke, die Liste von MainMa ist sehr vollständig. Ich werde nur einige meiner eigenen hinzufügen:

  1. Lesen Sie Eric Lipperts Artikel darüber, wie er Ausnahmen kategorisiert. Besonders wichtig ist, dass er keine Ausnahmen abfängt, die in Wirklichkeit Fehler in Ihrem Code sind. Korrigieren Sie stattdessen den Code!
  2. Wenn Sie wissen, dass eine Ausnahme auftreten kann UND Sie etwas dagegen tun können, können Sie sie behandeln, aber den Umfang Ihres Try-Catch-Vorgangs einschränken und die jeweilige erwartete Ausnahme abfangen. Das heißt, mach das nicht:

public void Foo() {
    try {
        //get input from use
        //do calculations
        //open file
    }
    catch (Exception ex) {
       //handle exception
    }
}

Mach stattdessen folgendes:

public void Foo() {
    //get input from use
    //do calculations
    try {
        //open file
    }
    catch (FileOpenException ex) {
       //handle exception
    }
}
  • Verwenden Sie keine Ausnahmen für den Kontrollfluss. Werfen Sie beispielsweise keine ClientNotFoundException in einem Nachschlage-Dialogfeld (ein nicht gefundener Client ist in dieser Situation keine Ausnahme) und erwarten Sie, dass der aufrufende Code in diesem Fall die Meldung "Keine Ergebnisse gefunden" anzeigt.

  • Schlucke keine Ausnahmen!

  • Denken Sie daran, dass die Behandlung einer Ausnahme nur drei Dinge bedeuten kann:

    1. Wiederholen Sie den Vorgang. Nur gültig, wenn das Problem vorübergehend ist.
    2. Versuchen Sie es mit einer Alternative.
    3. Benachrichtigen Sie jemanden über das Problem. Nur gültig, wenn die Benachrichtigung umsetzbar ist, was bedeutet, dass der Benutzer etwas dagegen unternehmen kann.

    Wenn keine dieser Optionen zutrifft, sollten Sie diese Ausnahme wahrscheinlich nicht abfangen. Sie sollten es jedoch protokollieren und dann entweder den Vorgang abbrechen oder den Computer herunterfahren. Dies hängt natürlich davon ab, welche Anforderungen Sie an Korrektheit und Robustheit stellen.

Mike
quelle