2 Stimmen

C# SmtpClient.Send() - Jede Alternative (oder Begleiter) zur Behandlung der Ausnahme?

(Langjähriger Leser von SO, zum ersten Mal eine Frage.

Ich bin ziemlich neu in C#, die in der PHP/Ruby/Python-Welt für viele Jahre gewesen, so entschuldige ich, wenn dies eine dumme Frage ist).

Ich tue einige Wartung auf eine alte C# app, die abstürzt, wenn SmtpClient.Send() fehlschlägt. Aus dem wenig, das ich aus dem MSDN gelesen habe, kann ich den offensichtlichen Weg sehen, um dies zu beheben, aber meine Frage ist auch mit dem allgemeineren Fall betroffen.

Wie in der MSDN:

  try {
          client.Send(message);
  }  
  catch (Exception ex) {
          Console.WriteLine("Exception caught in CreateTestMessage2(): {0}", 
                ex.ToString() );
  }

Das alles erscheint mir sinnvoll, aber ich habe auch immer gedacht, dass man immer dann, wenn man die Möglichkeit eines Fehlers verhindern kann, dies auch tut. Gibt es irgendetwas, das Sie hier tun können (und sollten?), um die Möglichkeit zu verringern, dass Send() Ausnahmen auslöst?

Ich gehe davon aus, dass es Situationen gibt, in denen es unmöglich ist, die Möglichkeit einer Ausnahme zu verhindern, so dass man damit umgehen muss, aber gibt es irgendwelche allgemeinen Stilrichtlinien oder Regeln, an denen sich die Leute orientieren?

Nochmals: Tut mir leid, wenn das eine blöde Frage ist. Ich habe versucht, SO und Google zu suchen, so viel wie ich konnte.

EDIT: Ich habe gerade diese Frage gefunden Bewährte Verfahren für die Verwaltung von Ausnahmen in Java oder C die meine Frage vielleicht ein Stück weit beantworten können.

EDIT2: Danke für die prompte Rückmeldung, unglaublich schnell. Ich habe über das Problem ein bisschen mehr nachgedacht und vielleicht könnte dies weiter zu verfeinern, was ich frage.

Ist es richtig zu sagen, dass bestimmte Ausnahmen, wie SmtpException, wirklich nicht vermieden werden können? Ist es noch richtiger zu sagen, dass es der richtige Stil ist, Ausnahmen wie SmtpException zu verwenden, um Ihnen mitzuteilen, dass bei der Übertragung etwas schief gelaufen ist, und dass Sie damit umgehen können, wie Sie es möchten?

Ich habe das Gefühl, dass ich mit dieser Frage ein bisschen dumm dastehe, aber ich frage, weil alles, was ich lernen kann, gut für mein Selbstvertrauen ist.

1 Stimmen

Ohne zu wissen, was die Ausnahme(n) sind, ist es schwierig, Ihre Frage zu beantworten. Es sieht so aus, als gäbe es 6 verschiedene Ausnahmen, die ausgelöst werden können. Sie könnten Ihre Eingabe validieren, um jeden möglichen Typ zu verhindern, oder nur diejenigen abfangen, die Sie behandeln können.

4voto

Eric Lippert Punkte 628543

Dies ist ein gutes Beispiel für das, was ich eine "exogene" Ausnahmesituation nenne.

http://ericlippert.com/2008/09/10/vexing-exceptions/

Betrachten wir einen analogen Fall - das Öffnen einer Datei. Sie können die Wahrscheinlichkeit, eine Ausnahme zu erhalten, verringern, indem Sie:

  • Prüfung, ob die Datei existiert
  • Prüfung, ob der Benutzer die Erlaubnis hat, die Datei zu öffnen
  • Prüfung, ob eine andere Anwendung die Datei gesperrt hat
  • blah
  • blah blah
  • blah blah blah

Sie können all das tun und erhalten trotzdem eine Ausnahme, wenn Sie die Datei öffnen. Denn zwischen all diesen Prüfungen und dem Versuch, die Datei zu öffnen, könnte sich etwas geändert haben. Ein anderer Prozess könnte die Berechtigungen geändert oder die Datei gesperrt haben, oder der Benutzer hat die CD-ROM aus dem Laufwerk entfernt, oder was auch immer. Ob die Aktion erfolgreich ist oder nicht, hängt von einer exogenen, realen Bedingung ab, die Sie nicht auf irgendeine garantierte Weise testen können.

Exogene Ausnahmen sind ein Ärgernis, weil man sie behandeln MUSS, auch wenn man sich viel Mühe gibt, sie zu beseitigen.

Das Versenden von Postsendungen erfolgt auf die gleiche Weise. Sie können alles Mögliche überprüfen, um die Ausnahme zu beseitigen, was wahrscheinlich in 99 % der Fälle funktioniert, aber Sie können nicht garantieren, dass zwischen all Ihren Überprüfungen und dem tatsächlichen Versuch, E-Mails zu senden, nicht jemand den Router genau im falschen Moment ausgesteckt hat. Sie müssen sich damit abfinden und die Ausnahmen in Kauf nehmen.

3voto

Wenn Sie Ausnahmen abfangen, sollten Sie so spezifisch wie möglich sein, wenn Sie wissen, welche Arten von Ausnahmen Sie von der aufgerufenen Methode erwarten. So können z. B. Fehler wie OutOfMemoryException auf dem Stapel weiter nach oben wandern, wo sie nicht behandelt werden sollten, und Ihre Anwendung wird schnell fehlschlagen (was wahrscheinlich gut ist, da sich Ihr System jetzt in einem unbekannten Zustand befindet und Sie nicht weitermachen sollten).

In einigen Fällen (z. B. bei einem NT-Dienst) ist eine hohe Verfügbarkeit der Anwendung erwünscht, und ein Absturz in der Produktion aufgrund einer NullPointerException auf einem unvorhergesehenen Codepfad ist nicht wünschenswert, solange diese Ausnahme protokolliert wird und Sie die Möglichkeit haben, eine QFE zu erstellen (ganz zu schweigen von der Überarbeitung Ihres Testsystems). Bei einer Konsolen- oder Formularanwendung ist die Wiederherstellung eine andere Geschichte, da die Ausnahme dem Benutzer angezeigt werden könnte und er interaktiv entscheiden kann, was die geeignete Aktion ist.

Mein allgemeiner Rat: fangen Sie bestimmte Ausnahmen so nah an der Quelle wie möglich ab, lassen Sie den Rest auf dem Stapel aufsteigen und lassen Sie ihn an einem Punkt protokollieren, an dem Sie genug Kontext haben, um später zu versuchen, die Ausnahme zu reprodieren. Seien Sie vorsichtig, dass das Abfangen und erneute Auslösen teuer ist; ein Szenario in Ihrem Beispiel, in dem Sie dies tun möchten, wäre, wenn, sagen wir, die SmtpException eine Zeitüberschreitung der Verbindung war (ich denke mir das aus), dann könnte eine Strategie sein, exponentiell zurückzugehen und es bis zu n-mal erneut zu versuchen, da der Mailserver ausgefallen sein könnte, und dann schließlich aufzugeben und erneut auszulösen, wenn Sie keinen Erfolg haben.

Die wirklich kurze Antwort lautet: Es kommt darauf an.

1voto

STW Punkte 42452

Auf MSDN finden Sie eine Liste der Ausnahmen, die von der Methode .Send() ausgelöst werden, und eine kurze Begründung, warum sie ausgelöst werden. Die Überprüfung auf diese Ausnahmen und ihre Behandlung vor dem Aufruf von Send() kann helfen, sie zu vermeiden - aber die Dokumentation deckt nicht unbedingt alle möglichen Ausnahmen oder Gründe für ihr Auftreten ab.

Sie sind jedoch auf dem richtigen Weg, und Sie haben Recht, dass Sie die Erstellung von Ausnahmen nach Möglichkeit vermeiden wollen. Wenn aus keinem anderen Grund sind sie ziemlich teuer für die Laufzeit zu erstellen und zu behandeln - und wenn sie unbehandelt gehen sogar eine einfache Ausnahme kann die ganze App zum Absturz bringen.

1voto

Die Ausnahmen sind an sich nicht sehr schlimm. Sie sind Teil einer defensiven Programmierstrategie. Durch das Abfangen von Ausnahmen erhalten Sie wertvolle Erkenntnisse über die Ursachen des Absturzes von Send. Diese können Sie nutzen, um die Probleme zu beheben.

0voto

Steven Sudit Punkte 19005

Es ist völlig in Ordnung, eine Ausnahme zu machen, wenn ein außergewöhnlicher Fehler auftritt, es gibt also keinen Fehler in Ihrem Code. Wenn der SMTP-Server nicht funktioniert, die E-Mail-Adresse ungültig ist oder ein anderer Fehler auftritt, können Sie wollen es zu werfen, anstatt stillschweigend zu scheitern.

Ob Sie einen Versuchsblock in unmittelbarer Nähe der Sendung wünschen, hängt davon ab, ob Sie hier etwas zu tun haben. Andernfalls können Sie es genauso gut bis zum äußersten Try-Block durchlaufen lassen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X