it-swarm.com.de

Wie Try Catch für Ausnahmebehandlung verwendet wird, ist die beste Vorgehensweise

ich halte den Code meines Kollegen auch von jemandem aufrecht, der behauptet, er wäre ein älterer Entwickler. Ich sehe jedoch oft den folgenden Code:

try
{
  //do something
}
catch
{
  //Do nothing
}

oder manchmal schreiben sie Protokollinformationen in folgende Protokolldateien wie den folgenden try catch-Block 

try
{
  //do some work
}
catch(Exception exception)
{
   WriteException2LogFile(exception);
}

Ich frage mich nur, ob sie die beste Vorgehensweise sind? Es macht mich verwirrt, weil in meinem Denken die Benutzer wissen sollten, was mit dem System passiert.

Bitte gib mir ein paar Ratschläge.

186
Toan Nguyen

Meine Ausnahmebehandlungsstrategie lautet:

  • Um alle nicht behandelten Ausnahmen zu fangen, indem Sie sich mit dem Application.ThreadException event verbinden, dann entscheiden Sie:

    • Für eine Benutzeroberflächenanwendung: Zum Anzeigen einer Entschuldigungsnachricht an den Benutzer (winforms)
    • Für einen Dienst oder eine Konsolenanwendung: Protokollieren Sie diese in einer Datei (Dienst oder Konsole).

Dann füge ich immer jedes Stück Code, das extern ausgeführt wird in try/catch ein:

  • Alle von der Winforms-Infrastruktur ausgelösten Ereignisse (Load, Click, SelectedChanged ...)
  • Alle Ereignisse, die von Komponenten von Drittanbietern ausgelöst werden

Dann lege ich 'try/catch' bei

  • Alle Operationen, die ich kenne, funktionieren möglicherweise nicht immer (E/A-Operationen, Berechnungen mit einer potenziellen Nulldivision ... ). In einem solchen Fall werfe ich eine neue ApplicationException("custom message", innerException), um zu verfolgen, was wirklich passiert ist

Außerdem versuche ich mein Bestes, um Ausnahmen richtig zu sortieren. Es gibt Ausnahmen, die:

  • müssen dem Benutzer sofort angezeigt werden
  • erfordern eine zusätzliche Verarbeitung, um Dinge zusammenzufügen, wenn sie auftreten, um Kaskadenprobleme zu vermeiden (z. B .: Setzen Sie .EndUpdate in den Abschnitt finally während einer TreeView-Füllung)
  • dem Benutzer ist es egal, aber es ist wichtig zu wissen, was passiert ist. Also logge ich sie immer:

    • Im Ereignisprotokoll
    • oder in einer .log-Datei auf der Festplatte

Es wird empfohlen, einige statische Methoden zur Behandlung von Ausnahmen zu entwerfen in den Fehlerbehandlungsroutinen der obersten Ebene der Anwendung.

Ich zwinge mich auch zu versuchen:

  • Denken Sie daran, ALLE Ausnahmen sprudeln bis zur obersten Ebene. Es ist nicht erforderlich, Ausnahmebehandlungsroutinen überall zu platzieren.
  • Wiederverwendbare oder tief aufgerufene Funktionen müssen keine Ausnahmen anzeigen oder protokollieren: Sie werden entweder automatisch gesprudelt oder mit einigen benutzerdefinierten Nachrichten in meinen Ausnahmebehandlungsroutinen erneut geworfen.

So endlich :

Schlecht:

// DON'T DO THIS, ITS BAD
try
{
    ...
}
catch 
{
   // only air...
}

Nutzlos:

// DONT'T DO THIS, ITS USELESS
try
{
    ...
}
catch(Exception ex)
{
    throw ex;
}

Endlich einen Versuch ohne einen Haken zu machen, ist absolut gültig:

try
{
    listView1.BeginUpdate();

    // If an exception occurs in the following code, then the finally will be executed
    // and the exception will be thrown
    ...
}
finally
{
    // I WANT THIS CODE TO RUN EVENTUALLY REGARDLESS AN EXCEPTION OCCURED OR NOT
    listView1.EndUpdate();
}

Was ich auf der obersten Ebene mache:

// i.e When the user clicks on a button
try
{
    ...
}
catch(Exception ex)
{
    ex.Log(); // Log exception

    -- OR --

    ex.Log().Display(); // Log exception, then show it to the user with apologies...
}

Was ich in einigen aufgerufenen Funktionen mache:

// Calculation module
try
{
    ...
}
catch(Exception ex)
{
    // Add useful information to the exception
    throw new ApplicationException("Something wrong happened in the calculation module :", ex);
}

// IO module
try
{
    ...
}
catch(Exception ex)
{
    throw new ApplicationException(string.Format("I cannot write the file {0} to {1}", fileName, directoryName), ex);
}

Es gibt viel mit der Ausnahmebehandlung zu tun (benutzerdefinierte Ausnahmen), aber diese Regeln, die ich zu beachten versuche, reichen für die einfachen Anwendungen aus, die ich mache.

Hier finden Sie ein Beispiel für Erweiterungsmethoden, mit denen abgefangene Ausnahmen auf komfortable Weise behandelt werden können. Sie sind so implementiert, dass sie miteinander verkettet werden können, und es ist sehr einfach, Ihre eigene Verarbeitung von gefangenen Ausnahmen hinzuzufügen.

// Usage:

try
{
    // boom
}
catch(Exception ex)
{
    // Only log exception
    ex.Log();

    -- OR --

    // Only display exception
    ex.Display();

    -- OR --

    // Log, then display exception
    ex.Log().Display();

    -- OR --

    // Add some user-friendly message to an exception
    new ApplicationException("Unable to calculate !", ex).Log().Display();
}

// Extension methods

internal static Exception Log(this Exception ex)
{
    File.AppendAllText("CaughtExceptions" + DateTime.Now.ToString("yyyy-MM-dd") + ".log", DateTime.Now.ToString("HH:mm:ss") + ": " + ex.Message + "\n" + ex.ToString() + "\n");
    return ex;
}

internal static Exception Display(this Exception ex, string msg = null, MessageBoxImage img = MessageBoxImage.Error)
{
    MessageBox.Show(msg ?? ex.Message, "", MessageBoxButton.OK, img);
    return ex;
}
293
Larry

Die beste Vorgehensweise ist, dass Ausnahmebehandlung niemals Probleme verbergen sollte. Dies bedeutet, dass try-catch-Blöcke äußerst selten sein sollten.

Es gibt 3 Umstände, unter denen ein try-catch sinnvoll ist.

  1. Behandeln Sie known -Ausnahmen immer so niedrig wie möglich. Wenn Sie jedoch eine Ausnahme erwarten, ist es in der Regel besser, zuerst zu testen. Zum Beispiel werden Parsen, Formatierungen und arithmetische Ausnahmen fast immer besser durch Logikprüfungen als durch einen bestimmten try-catch behandelt.

  2. Wenn Sie etwas für eine Ausnahme tun müssen (beispielsweise eine Transaktion protokollieren oder rückgängig machen), geben Sie die Ausnahme erneut aus.

  3. Behandeln Sie unknown -Ausnahmen immer so hoch wie möglich - der only -Code, der eine Ausnahme beanspruchen und nicht erneut werfen soll, sollte die Benutzeroberfläche oder die öffentliche API sein.

Angenommen, Sie stellen eine Verbindung zu einer Remote-API her. Hier wissen Sie, dass Sie bestimmte Fehler erwarten (und dies unter Umständen zu tun haben). In diesem Fall ist dies Fall 1:

try 
{
    remoteApi.Connect()
}
catch(ApiConnectionSecurityException ex) 
{
    // User's security details have expired
    return false;
}

return true;

Beachten Sie, dass keine anderen Ausnahmen erfasst werden, da sie nicht erwartet werden.

Angenommen, Sie versuchen, etwas in der Datenbank zu speichern. Wenn es fehlschlägt, müssen wir es zurücksetzen, daher haben wir Fall 2:

try
{
    DBConnection.Save();
}
catch
{
    // Roll back the DB changes so they aren't corrupted on ANY exception
    DBConnection.Rollback();

    // Re-throw the exception, it's critical that the user knows that it failed to save
    throw;
}

Beachten Sie, dass wir die Ausnahme erneut auslösen - der Code oben muss noch wissen, dass etwas fehlgeschlagen ist.

Endlich haben wir die Benutzeroberfläche - hier wollen wir keine völlig unbehandelten Ausnahmen haben, aber wir wollen sie auch nicht ausblenden. Hier haben wir ein Beispiel von Fall 3:

try
{
    // Do something
}
catch(Exception ex) 
{
    // Log exception for developers
    WriteException2LogFile(ex);

    // Display message to users
    DisplayWarningBox("An error has occurred, please contact support!");
}

In den meisten API- oder Benutzeroberflächen-Frameworks gibt es jedoch generische Methoden, um Fall 3 auszuführen. Beispielsweise hat ASP.Net einen gelben Fehlerbildschirm, der die Ausnahmedetails ausgibt, der in der Produktionsumgebung jedoch durch eine allgemeinere Nachricht ersetzt werden kann. Befolgen Sie diese Anweisungen, da dies eine Menge Code spart, aber auch, weil die Fehlerprotokollierung und die Anzeige von Konfigurationen abhängen sollten und nicht fest codiert sein sollten.

Dies alles bedeutet, dass Fall 1 (bekannte Ausnahmen) und Fall 3 (einmalige Benutzeroberflächenhandhabung) bessere Muster aufweisen (vermeiden Sie den erwarteten Fehler oder die Handfehlerbehandlung für die Benutzeroberfläche).

Sogar Fall 2 kann durch bessere Muster ersetzt werden, z. B. Transaktionsbereiche (using-Blöcke, die jede während des Blockes nicht festgeschriebene Transaktion rückgängig machen). 

Angenommen, Sie verfügen über eine umfangreiche ASP.Net-Anwendung. Die Fehlerprotokollierung kann über ELMAH erfolgen, die Fehleranzeige kann eine informative YSoD-Datei und eine lokalisierte Nice-Meldung in der Produktion sein. Datenbankverbindungen können alle über Transaktionsbereiche und using-Blöcke erfolgen. Sie benötigen keinen einzelnen try-catch-Block.

TL; DR: Es empfiehlt sich, try-catch-Blöcke überhaupt nicht zu verwenden.

55
Keith

Eine Ausnahme ist ein Sperrfehler .

Zuallererst sollte die beste Vorgehensweise sein, keine Ausnahmen für Fehler jeglicher Art auszulösen, es sei denn, es handelt sich um einen blockierenden Fehler .

Wenn der Fehler blockiert , dann lasse die Ausnahme aus. Sobald die Ausnahme bereits ausgelöst wurde, muss sie nicht mehr ausgeblendet werden, da sie außergewöhnlich ist. Informieren Sie den Benutzer darüber (Sie sollten die gesamte Ausnahme zu etwas neu formatieren, das für den Benutzer in der Benutzeroberfläche nützlich ist).

Ihre Aufgabe als Softwareentwickler ist es, einen Ausnahmefall zu vermeiden, bei dem ein Parameter oder eine Laufzeitsituation in einer Ausnahme enden kann. Das heißt, Ausnahmen dürfen nicht stummgeschaltet werden, aber diese müssen vermieden werden .

Wenn Sie beispielsweise wissen, dass einige Ganzzahleingaben ein ungültiges Format aufweisen können, verwenden Sie int.TryParse anstelle von int.Parse. Es gibt viele Fälle, in denen Sie dies tun können, anstatt nur zu sagen: "Wenn es fehlschlägt, werfen Sie einfach eine Ausnahme.".

Ausnahmen zu werfen ist teuer.

Wenn schließlich eine Ausnahme ausgelöst wird, anstatt die Ausnahme nach dem Auslösen in das Protokoll zu schreiben, ist es eine der bewährten Methoden, sie in einem Ausnahmehandler der ersten Chance abzufangen . Zum Beispiel:

  • ASP.NET: Global.asax Application_Error
  • Andere: AppDomain.FirstChanceException-Ereignis .

Mein Standpunkt ist, dass lokale Try/Catches besser für die Behandlung von Sonderfällen geeignet sind, in denen Sie eine Ausnahme in eine andere übersetzen oder wenn Sie sie für einen sehr, sehr, sehr, sehr, sehr speziellen Fall "stummschalten" möchten (einen Bibliotheksfehler) eine nicht verwandte Ausnahme auslösen, die Sie stumm schalten müssen, um den gesamten Fehler zu umgehen).

Für den Rest der Fälle:

  • Versuchen Sie, Ausnahmen zu vermeiden.
  • Wenn dies nicht möglich ist: Ausnahmebehandlungsroutinen der ersten Chance.
  • Oder verwenden Sie einen PostSharp-Aspekt (AOP).

Beantwortung eines Kommentars an @thewhiteambit ...

@thewhiteambit sagte:

Ausnahmen sind keine schwerwiegenden Fehler, sondern Ausnahmen! Manchmal handelt es sich nicht einmal um Fehler, aber wenn man sie als schwerwiegende Fehler betrachtet, ist dies ein völlig falsches Verständnis der Ausnahmen.

Wie kann eine Ausnahme nicht einmal ein Fehler sein?

  • Keine Datenbankverbindung => Ausnahme.
  • Ungültiges Zeichenfolgenformat zum Parsen auf einen Typ => Ausnahme
  • Der Versuch, JSON zu analysieren und während der Eingabe, ist eigentlich keine JSON => Ausnahme
  • Argument null während Objekt erwartet wurde => Ausnahme
  • Einige Bibliotheken haben einen Fehler => lösen eine unerwartete Ausnahme aus
  • Es gibt eine Socket-Verbindung und die Verbindung wird getrennt. Dann versuchen Sie eine Nachricht zu senden => Ausnahme
  • ...

Wir können 1k Fälle auflisten, in denen eine Ausnahme ausgelöst wird, und schließlich sind alle möglichen Fälle ein Fehler .

Eine Ausnahme ist ein Fehler, da es sich am Ende des Tages um ein Objekt handelt, das Diagnoseinformationen sammelt - es hat eine Meldung und es passiert, wenn etwas schief geht.

Niemand würde eine Ausnahme auslösen, wenn es keinen Ausnahmefall gibt. Ausnahmen sollten blockierende Fehler sein , da Sie, wenn Sie einmal geworfen sind, try/catch und Ausnahmen verwenden, um die Steuerung zu implementieren, wenn Sie nicht versuchen, in die zu fallen flow bedeutet, dass Ihre Anwendung/Ihr Dienst den Vorgang beendet, der in einen Ausnahmefall eingetreten ist.

Außerdem empfehle ich jedem, das Fail-Fast -Paradigma zu überprüfen veröffentlicht von Martin Fowler (und geschrieben von Jim Shore) . So habe ich es immer verstanden, mit Ausnahmen umzugehen, noch bevor ich vor einiger Zeit zu diesem Dokument gekommen bin.

Fatal-Errors ist ein völlig falsches Verständnis der Ausnahmen.

In der Regel wird durch Ausnahmen ein Teil des Operationsflusses unterbrochen und in für den Menschen verständliche Fehler umgewandelt. Es scheint also, als wäre eine Ausnahme tatsächlich ein besseres Paradigma, um Fehlerfälle zu behandeln und sie zu bearbeiten, um einen Absturz der Anwendung/des Dienstes zu vermeiden und den Benutzer/Verbraucher zu benachrichtigen, dass etwas schief gelaufen ist.

Weitere Antworten zu @thewhiteambit betrifft

Beispielsweise könnte das Programm bei einer fehlenden Datenbankverbindung ausnahmsweise in eine lokale Datei weiter schreiben und die Änderungen an die Datenbank senden, sobald diese wieder verfügbar ist. Ihr ungültiges String-to-Number-Casting könnte erneut mit der sprachlokalen Interpretation von Exception analysiert werden, da Sie beispielsweise versuchen, die englische Standardsprache zu analysieren ("1,5"), und Sie versuchen es erneut mit der deutschen Interpretation, die vollständig ist gut, weil wir Komma anstelle von Punkt als Trennzeichen verwenden. Sie sehen, diese Ausnahmen dürfen nicht einmal blockiert sein, sie benötigen nur eine Ausnahmebehandlung.

  1. Wenn Ihre App möglicherweise offline funktioniert, ohne dass Daten in der Datenbank gespeichert werden, sollten Sie keine Ausnahmen verwenden, da die Implementierung des Kontrollflusses mit try/catch als Antimuster betrachtet wird. Offline-Arbeit ist ein möglicher Anwendungsfall. Sie implementieren also einen Kontrollfluss, um zu überprüfen, ob auf die Datenbank zugegriffen werden kann, und warten nicht, bis sie nicht mehr erreichbar ist .

  2. Das Parsen ist auch ein erwarteter Fall ( kein AUSNAHMEFALL ). Wenn Sie dies erwarten, , verwenden Sie keine Ausnahmen, um den Fluss zu steuern! . Sie erhalten einige Metadaten vom Benutzer, um zu wissen, was seine/ihre Kultur ist, und Sie verwenden dafür Formatierer! . NET unterstützt auch diese und andere Umgebungen und eine Ausnahme, da die Zahlenformatierung vermieden werden muss, wenn Sie eine kulturspezifische Verwendung Ihrer Anwendung/Ihres Dienstes erwarten .

Eine nicht behandelte Ausnahme wird normalerweise zu einem Fehler. Ausnahmen selbst sind jedoch keine codeproject.com/Articles/15921/Not-All-Exceptions-Are-Errors

Dieser Artikel ist nur eine Meinung oder ein Standpunkt des Autors.

Da Wikipedia auch nur die Meinung von Artikelautoren sein kann, würde ich nicht sagen, dass es das Dogma ist , aber überprüfen Sie, was Codierung nach Ausnahme Artikel sagt irgendwo in einem Absatz:

[...] Die Verwendung dieser Ausnahmen zur Behandlung bestimmter Fehler, die auftreten, um das Programm fortzusetzen, wird als Codierung in Ausnahmefällen bezeichnet. Dieses Anti-Pattern kann die Leistung und Wartbarkeit von Software schnell beeinträchtigen.

Es heißt auch irgendwo:

Falsche Ausnahmeverwendung

Oft kann das Codieren ausnahmsweise zu weiteren Problemen in der Software führen, wenn die Ausnahmebedingung nicht korrekt verwendet wird. Zusätzlich zur Verwendung der Ausnahmebehandlung für ein eindeutiges Problem führt eine inkorrekte Ausnahmebehandlung dazu, dass Code auch nach dem Auslösen der Ausnahme ausgeführt wird. Diese schlechte Programmiermethode ähnelt der goto-Methode in vielen Softwaresprachen, tritt jedoch erst auf, nachdem ein Problem in der Software festgestellt wurde.

Ehrlich gesagt glaube ich, dass Software nicht entwickelt werden kann, ohne Use Cases ernst zu nehmen. Wenn Sie das wissen ...

  • Ihre Datenbank kann offline gehen ...
  • Einige Dateien können gesperrt werden ...
  • Einige Formatierungen werden möglicherweise nicht unterstützt ...
  • Einige Domänenüberprüfungen schlagen möglicherweise fehl ...
  • Deine App sollte im Offline-Modus funktionieren ...
  • welcher Anwendungsfall auch immer ...

... Sie werden keine Ausnahmen dafür verwenden . Sie würden diese Anwendungsfälle unter Verwendung eines regulären Kontrollflusses unterstützen .

Und wenn ein unerwarteter Anwendungsfall nicht behandelt wird, schlägt Ihr Code schnell fehl, da eine Ausnahme auslöst . Richtig, denn eine Ausnahme ist ein Ausnahmefall .

In der anderen Hand und schließlich decken Sie manchmal Ausnahmefälle ab, die erwartete Ausnahmen auslösen, aber Sie ziehen an werfen Sie sie nicht, um Kontrollfluss zu implementieren. Sie tun dies, weil Sie übergeordnete Ebenen darüber informieren möchten, dass Sie einen bestimmten Anwendungsfall nicht unterstützen oder Ihr Code mit bestimmten Argumenten oder Umgebungsdaten/-eigenschaften nicht funktioniert.

32

Ich weiß, dass dies eine alte Frage ist, aber niemand hat den MSDN-Artikel hier erwähnt, und es war das Dokument, das es tatsächlich für mich geklärt hat. MSDN hat ein sehr gutes Dokument dabei sollten Sie Ausnahmen unter den folgenden Bedingungen feststellen sind wahr:

  • Sie haben ein gutes Verständnis dafür, warum möglicherweise eine Ausnahme ausgelöst wird, und Sie können eine bestimmte Wiederherstellung implementieren, z. B. den Benutzer auffordern, einen neuen Dateinamen einzugeben, wenn Sie ein FileNotFoundException-Objekt abfangen.

  • Sie können eine neue, spezifischere Ausnahme erstellen und auslösen.

int GetInt(int[] array, int index)
{
    try
    {
        return array[index];
    }
    catch(System.IndexOutOfRangeException e)
    {
        throw new System.ArgumentOutOfRangeException(
            "Parameter index is out of range.");
    }
}
  • Sie möchten eine Ausnahme teilweise behandeln, bevor Sie sie zur weiteren Behandlung weiterleiten. Im folgenden Beispiel wird ein catch-Block verwendet, um einen Eintrag zu einem Fehlerprotokoll hinzuzufügen, bevor die Ausnahme erneut ausgelöst wird.
    try
{
    // Try to access a resource.
}
catch (System.UnauthorizedAccessException e)
{
    // Call a custom error logging procedure.
    LogError(e);
    // Re-throw the error.
    throw;     
}

Ich würde vorschlagen, den gesamten Abschnitt " Exceptions and Exception Handling " und auch Best Practices für Exceptions zu lesen.

5
Hamid Mosalla

Sie sollten Ihre Benutzer nur über etwas beunruhigen, das im Code passiert ist, wenn sie etwas tun können oder müssen, um das Problem zu vermeiden. Wenn sie Daten in einem Formular ändern können, klicken Sie auf die Schaltfläche oder ändern Sie die Anwendungseinstellungen, um das Problem zu vermeiden, und informieren Sie sie. Aber Warnungen oder Fehler, die der Benutzer nicht vermeiden kann, verlieren nur das Vertrauen in Ihr Produkt. 

Ausnahmen und Protokolle gelten für Sie, den Entwickler und nicht für Ihren Endbenutzer. Wenn Sie jede Ausnahme wahrnehmen, ist es viel besser, wenn Sie das richtige verstehen, als nur eine goldene Regel anzuwenden oder sich auf ein anwendungsweites Sicherheitsnetz zu verlassen.

Mindless-Codierung ist die einzige Art der falschen Codierung. Die Tatsache, dass Sie der Meinung sind, dass in diesen Situationen etwas Besseres möglich ist, zeigt, dass Sie in gutes Coding investieren. Versuchen Sie jedoch nicht, in diesen Situationen eine generische Regel zu stempeln und den Grund dafür zu verstehen, dass etwas überhaupt erst geworfen wird Sie können tun, um sich davon zu erholen.

5
ChrisCW

Der bessere Ansatz ist der zweite (der, bei dem Sie den Ausnahmetyp angeben). Der Vorteil davon ist, dass Sie wissen, dass diese Art von Ausnahme in Ihrem Code auftreten kann. Sie behandeln diese Art von Ausnahme und können fortfahren. Wenn eine andere Ausnahme auftrat, bedeutet dies, dass etwas nicht stimmt, was Ihnen hilft, Fehler in Ihrem Code zu finden. Die Anwendung wird schließlich abstürzen, aber Sie werden wissen, dass Sie etwas verpasst haben (Bug), das behoben werden muss.

1
fhnaseer

Der zweite Ansatz ist gut.

Wenn Sie den Fehler nicht anzeigen und den Benutzer der Anwendung verwirren möchten, indem Sie eine Laufzeitausnahme (d. H. Fehler) zeigen, die sich nicht auf sie bezieht, können Sie den Fehler einfach protokollieren und das technische Team kann das Problem suchen und beheben.

try
{
  //do some work
}
catch(Exception exception)
{
   WriteException2LogFile(exception);//it will write the or log the error in a text file
}

Ich empfehle Ihnen, den zweiten Ansatz für Ihre gesamte Anwendung zu wählen.

1
Pranay Rana

Es empfiehlt sich, eine Exception auszulösen, wenn der Fehler auftritt. Weil ein Fehler aufgetreten ist und nicht ausgeblendet werden sollte.

Im wirklichen Leben kann es jedoch mehrere Situationen geben, in denen Sie dies verbergen möchten

  1. Sie verlassen sich auf eine Drittanbieter-Komponente und möchten das Programm im Fehlerfall fortsetzen.
  2. Sie haben einen Geschäftsfall, den Sie im Fehlerfall fortsetzen müssen
0
Gregory Nozik

Leer lassen Fangblock ist das Schlimmste. Wenn ein Fehler aufgetreten ist, können Sie am besten damit umgehen:

  1. Melden Sie es in Datei\Datenbank usw. an.
  2. Versuchen Sie, es im laufenden Betrieb zu beheben (versuchen Sie es vielleicht auf alternative Weise, um diese Operation auszuführen)
  3. Wenn wir das nicht beheben können, benachrichtigen Sie den Benutzer über einen Fehler und brechen den Vorgang natürlich ab
0
Stasel

Ich kann dir etwas sagen:

Snippet # 1 ist nicht akzeptabel, da es Ausnahmen ignoriert. (Es schluckt es, als wäre nichts passiert).

Fügen Sie also keinen catch-Block hinzu, der nichts tut oder nur neu wirft.

Der Catch-Block sollte einen Mehrwert bieten. Zum Beispiel Nachricht an Endbenutzer ausgeben oder Fehler protokollieren.

Verwenden Sie keine Ausnahme für die normale Ablaufprogrammlogik. Zum Beispiel:

z.B. Eingabevalidierung. <- Dies ist keine gültige Ausnahmesituation. Schreiben Sie stattdessen die Methode IsValid(myInput);, um zu überprüfen, ob das Eingabeelement gültig ist oder nicht.

Konstruktionscode, um Ausnahmen zu vermeiden. Zum Beispiel:

int Parse(string input);

Wenn wir einen Wert übergeben, der nicht in int geparst werden kann, würde diese Methode eine Ausnahme auslösen, stattdessen könnten wir so etwas schreiben:

bool TryParse(string input,out int result); <- Diese Methode gibt einen Booleschen Wert zurück, der angibt, ob die Analyse erfolgreich war.

Vielleicht ist dies ein bisschen von dieser Frage ausgeschlossen, aber ich hoffe, dies wird Ihnen helfen, die richtigen Entscheidungen zu treffen, wenn es um try {} catch(){} und Ausnahmen geht.

0
Roxy'Pro

Manchmal müssen Sie Ausnahmen behandeln, die den Benutzern nichts mitteilen.

Mein Weg ist:

  • Nicht erfasste Ausnahmen auf Anwendungsebene (dh in global.asax) für kritische Ausnahmen abfangen (Anwendung kann nicht nützlich sein). Diese Ausnahmen fange ich nicht an. Melden Sie sie einfach auf App-Ebene an und lassen Sie das System seine Arbeit erledigen.
  • Fangen Sie "on place" und zeigen Sie dem Benutzer einige nützliche Informationen (falsche Nummer eingegeben, kann nicht analysiert werden).
  • Fangen Sie vor Ort und tun Sie nichts bei geringfügigen Problemen wie "Ich werde nach Update-Informationen im Hintergrund suchen, aber der Dienst läuft nicht".

Es muss definitiv nicht die beste Praxis sein. ;-)

0
Fanda

Mit Ausnahmen versuche ich Folgendes:

Zuerst fange ich spezielle Ausnahmetypen wie Division durch Null, IO -Operationen usw. an und schreibe entsprechend Code. Zum Beispiel eine Division durch Null, abhängig von der Herkunft der Werte könnte ich den Benutzer warnen (beispielsweise einen einfachen Rechner, bei dem in einer mittleren Berechnung (nicht die Argumente) bei einer Division durch Null ankommen) oder diese Ausnahme lautlos behandeln, Protokollierung es und weiterarbeiten.

Dann versuche ich, die restlichen Ausnahmen abzufangen und zu protokollieren. Wenn möglich, die Ausführung von Code zulassen, andernfalls den Benutzer auf einen Fehler aufmerksam machen und ihn auffordern, einen Fehlerbericht zu senden.

Im Code etwa so:

try{
    //Some code here
}
catch(DivideByZeroException dz){
    AlerUserDivideByZerohappened();
}
catch(Exception e){
    treatGeneralException(e);
}
finally{
    //if a IO operation here i close the hanging handlers for example
}
0
Sorcerer86pt

Ausnahmebehandlung kann für mich als Geschäftsregel betrachtet werden. Offensichtlich ist der erste Ansatz inakzeptabel. Die zweite ist besser und es kann zu 100% korrekt sein, wenn der Kontext dies sagt. Jetzt entwickeln Sie beispielsweise ein Outlook-Add-In. Wenn Sie ein Addin mit einer nicht behandelten Ausnahme auslösen, weiß der Outlook-Benutzer dies möglicherweise, da sich Outlook nicht selbst aufgrund eines fehlgeschlagenen Plugins zerstört. Und es fällt Ihnen schwer, herauszufinden, was schief gelaufen ist. Daher ist der zweite Ansatz in diesem Fall für mich richtig. Neben der Protokollierung der Ausnahme können Sie sich dazu entscheiden, dem Benutzer eine Fehlernachricht anzuzeigen - ich halte dies für eine Geschäftsregel.

0
Thai Anh Duc

Sie sollten diese Designrichtlinien für Ausnahmen berücksichtigen

  • Ausnahme zu werfen
  • Standardausnahmetypen verwenden
  • Ausnahmen und Leistung

https://docs.Microsoft.com/de-de/dotnet/standard/design-guidelines/exceptions

0
Jaider

Die catch ohne Argumente ist einfach eating die Ausnahme und nützt nichts. Was ist, wenn ein schwerwiegender Fehler auftritt? Es gibt keine Möglichkeit zu wissen, was passiert ist, wenn Sie catch ohne Argument verwenden.

Eine catch-Anweisung sollte spezifische -Ausnahmen abfangen, wie FileNotFoundException, und ganz am end sollten Sie Exception abfangen, die andere Ausnahmen fangen und diese protokollieren würden.

0
Anirudha