Laden...

Unhandled Exceptions als Build Error?

Erstellt von zidjian vor 15 Jahren Letzter Beitrag vor 15 Jahren 1.891 Views
Z
zidjian Themenstarter:in
6 Beiträge seit 2008
vor 15 Jahren
Unhandled Exceptions als Build Error?

Hallo ihr,

bin noch ziemlich neu in der Programmierung mit C# und habe bisher viel mit Java gemacht.
Daher bin ich es aus Java gewohnt, dass jede Exception auch behandelt werden muss, da ansonsten vom Compiler ein Fehler erzeugt wird. Das fand ich auch eigentlich sehr angenehm, da so keine Ausnahme vergessen werden kann.
Nun meckert ja in C# keiner meckert, wenn man sich um die Ausnahmen nicht kümmert.
Kann man das vielleicht irgendwie einstellen dass mir von der IDE angezeigt wird, wenn Unbehandelte Ausnahmen auftreten? Habe schon alle Einstelklungen durchgesehen, aber leider nichts passendes gefunden.
Finde es so ein bisschen mühsam jedes mal nachschauen zu müssen, was welche Exception schmeißen kann, und so übersieht man eben doch mal was.

Ich benutzte als IDE Visual Studio 2005 Professional.

Vielen lieben Dank schon mal.
Grüße
zidjian

Gelöschter Account
vor 15 Jahren

nein so etwas geht in c# nicht aber du kannst im notfall (soll man allerdings nicht amchen) die basisklasse Exception fangen.

Z
zidjian Themenstarter:in
6 Beiträge seit 2008
vor 15 Jahren

ja, das mach ich ja auch in meiner Main, aber das is ja nur so der letzte Notnagel, damit der User im Falle wenigstens noch ne Ordentliche Fehlermeldung bekommt.

Dass ich eigentlich auf jede Ausnahme individuell reagieren möchte is klar, nur eben find ich es ziemlich mühsam jede mögliche Ausnahme auch zu finden...

888 Beiträge seit 2007
vor 15 Jahren

Schau Dir mal hier das Snipped von Jürgen Bayer an:

044a: Exceptions in Anwendungen korrekt auswerten

So mach ich das immer noch zusätzlich.

Z
zidjian Themenstarter:in
6 Beiträge seit 2008
vor 15 Jahren

Hi Joe,

erstmal danke für den Link.

Allerdings zeigt er da ja nur wie man generell Exceptions behandelt.
Das is mir eigentlich schon klar.

Was ich suche is ne Lösung, in der die IDE dem Programmierer darauf Aufmerksam macht, dass eine mögliche Ausnahme nicht behandelt wurde.
So von wegen:
"Achtung! Hier wird eine Methode aufgerufen, die eine Ausnahme erzeugen könnte und du fängst sie nicht ab. Bitte kümmer dich darum."

C
252 Beiträge seit 2007
vor 15 Jahren

Also dann dürfte Exception Hunter genau das sein was du suchst.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo zidjian,

in Java können Ausnahmen so deklariert werden, dass sie auch verarbeitet werden müssen (checked Exception). In C# hingegen ist es nicht notwendig und absichtlich nicht möglich, Ausnahmen (exceptions) zu einer Methode zu deklarieren.

Konsequenterweise gibt es keine Prüfung im Compiler und aller Wahrscheinlichkeit nach auch nicht in der IDE.

Ich kann mir aber gut vorstellen, dass es entsprechende VS-Plugins oder eigenständige Tools für diese Aufgabe gibt.

Davon abgesehen gibt es nur ganz wenige Stellen, an denen ich persönlich nach der tatsächlich aufgetretenen Exception differenziere. Ich weiß, da gibt es auch andere Meinungen zu dem Thema, aber solange an einer Stelle die Behandlung für alle Exception sowieso gleich ist (z.B. sie anzuzeigen), braucht man auch nicht zu differenzieren. Wenn man das aber nicht tut, stellt sich die Frage, welche Exceptions denn eigentlich auftreten können - und damit dein Problem - auch gar nicht.

herbivore

6.862 Beiträge seit 2003
vor 15 Jahren

...In C# hingegen ist es nicht notwendig und absichtlich nicht möglich, Ausnahmen (exceptions) zu einer Methode zu deklarieren...

Zu dem Warum gibts dieses bekannte Interview mit Anders Hejlsberg.

Baka wa shinanakya naoranai.

Mein XING Profil.

Z
zidjian Themenstarter:in
6 Beiträge seit 2008
vor 15 Jahren

...In C# hingegen ist es nicht notwendig und absichtlich nicht möglich, Ausnahmen (exceptions) zu einer Methode zu deklarieren...
Zu dem Warum gibts
>
bekannte Interview mit Anders Hejlsberg.

Vielen Dank für den Link. Echt gut um die Hintergründe dazu zu verstehen.
Und spart natürlich auch weitere Diskussionen 😉

Trotzdem find ichs schade. Ich finde die sind in manchen Fällen echt nützlich.

Davon abgesehen gibt es nur ganz wenige Stellen, an denen ich persönlich nach der tatsächlich aufgetretenen Exception differenziere. Ich weiß, da gibt es auch andere Meinungen zu dem Thema, aber solange an einer Stelle die Behandlung für alle Exception sowieso gleich ist (z.B. sie anzuzeigen), braucht man auch nicht zu differenzieren.

Ja, bei Exceptions die eigentlich nie Auftreten sollen hast du da schon recht, die zeigt man an und gut is. Aber gibt doch einige Situationen wo die Exception aufgrund der Umgebung in welcher die Software läuft, oder aufgrund falsche Benutzereinstellungen beruht. Da möcht ich ja dann vielleicht gerne dem Benutzer spezielle Lösugen anbieten, oder vielleicht einen anderen Weg einschlagen.

Wenn man das aber nicht tut, stellt sich die Frage, welche Exceptions denn eigentlich auftreten können - und damit dein Problem - auch gar nicht.

Genau des find ich so eben ein bisschen mühsam, immer zu guggen was auftreten kann. Und da man hier keine Unterstützung durch die IDE hat übersieht man oder denkt vielleicht mal nicht an die eine oder andere Ausnahme.
Manche fallen so eben erst beim Life Einsatz bzw. Beta Testen auf.

In Java hat man Exceptions auch teilweise dazu missbraucht um einfach den Programmfluss zu steuern. Wie beispielsweise in einer Endlosschleife einen FileStream lesen bis eine EndOfFileException ausgelöst wird. Da mag natürlich auch der ein oder andere behaupten das is kein schöner Programmierstil, aber denke da kann man sich halt auch ewig streiten 😉

Trotzdem euch vielen Dank,
habt mir da ganz gut weitergeholfen, sonst hätte ich jetzt noch ewig gesucht, wie ich das lösen kann 😉

Grüße
zidjian

Z
zidjian Themenstarter:in
6 Beiträge seit 2008
vor 15 Jahren

Also dann dürfte
>
genau das sein was du suchst.

Oh, jetzt hab ich deinen Post unter den anderenfast übersehen X(

Ja is eigentlich ganz genau das was ich gesucht habe. 👍

Allerdings find ich $295 echt ein bisschen übertrieben für das Tool, obwohls natürlich ohne Zweifel zur Qualitätssicherung ziemlich hilfreich wär.
Werd mal morgen noch ein bischen googeln, obs da nicht noch andere Tools gibt.
Sonst muss ich mir des echt mal überlegen, wenn auch ungern... 🤔 ... naja wenigstens würde der Dollar Kurs mir ja entgegen kommen.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo zidjian,

Ja, bei Exceptions die eigentlich nie Auftreten sollen hast du da schon recht, die zeigt man an und gut is. Aber gibt doch einige Situationen wo die Exception aufgrund der Umgebung in welcher die Software läuft, oder aufgrund falsche Benutzereinstellungen beruht. Da möcht ich ja dann vielleicht gerne dem Benutzer spezielle Lösugen anbieten, oder vielleicht einen anderen Weg einschlagen.

ja, natürlich gibt es solche Situationen. Und natürlich würde man dann ein spezielle Fehlerbehandlung vornehmen. Ich meinte ja auch nur, dass ich nach meiner Erfahrung in vielen Fällen ohne eine spezialisierte Fehlerbehandlung auskomme und deshalb fast immer alle Exceptions fange. Und sollte ich doch eine spezialisiere Behandlung brauchen, besteht ja bei Bedarf immer noch die Möglichkeit nach dieser alle (restlichen) Exceptions zu fangen.

Davon abgesehen findet man zumindest für jedem Methode im Framework in der :rtfm: Doku, welche Exceptions dabei auftreten können.

herbivore

123 Beiträge seit 2008
vor 15 Jahren

Grundlegend behaupte ich, das man nur das fangen sollte, ++was man ++auch behandeln kann bzw. behandeln will.

Begründung:

Ich möchte die Begründung einmal an einem Praxisbeispiel, welches mir hier im Team passierte verdeutlichen.

Geschrieben wurde eine Klasse, deren Aufgabe ein aufwendiges Aufbereiten von Daten aus vielen Dateien und deren Versand über TCP/IP hatte. Die Klasse verwendete grundsätzlich einen Allesfänger, da es oft zu IOExceptions , FormatExceptions etc. kam. An sich ok, denn wenn die Datei nicht gelesen werden konnte (warum auch immer) sollte diese Ignoriert werden.

Jedoch fing diese Routine auch Fehler des Transfermoduls ab, der irgendwann vom Aufruf her verschoben wurde.

Nun gab es bei einem Kunden das Problem, das sich die Software merkwürdig verhielt und das Problem nicht reproduziert werden konnte. Da das ganze auf einem CF1 implementiert war, waren die Möglichkeiten des Loggens in einer speziellen "Debugversion" kaum durchführbar.

Es stellte sich heraus, das eine vielsagende Exception vom TCP/IP Modul geworfen und verschluckt wurde.

So wenig wie möglich Fangen

Daraus habe ich meine Einstellung, so wenig wie möglich zu fangen gefestigt.

Je tiefer die Schicht des Codes ist der geschrieben wird, um so weniger sollte man überhaupt Exceptions fangen. Je tiefer man steckt, um so weniger Ahnung hat man vom Umfeld und deren Möglichkeit, auf ein Problem einzugehen.

(ACHTUNG: Extrem einfaches Beispiel).
Schreibt man z.B. eine simple Routine, die einfach nur den Inhalt einer Datei liefern soll und fängt dabei die IOExceptions (oder schlimmer alle Exceptions) und liefert im Fehlerfalle String.Empty zurück, hat an als Aufrufer keine Möglichkeit heraus zu finden ob der Inhalt wirklich leer war oder ein Fehler auftrat. Reicht man die Exception weiter, muss der Aufrufer entscheiden ob der Fehlerfalle string.Empty bedeutet oder eine andere Aktion auslösen muss.

Die Kosten

Den Preis, den man hierfür zahlen muss sollte man noch deutlich erwähnen:

Die Software endet schneller in einem Prozessabbruch. Denn jedes Problem, welches nicht gefangen wurde, beendet den Prozess - und für den Kunden in einem Programmabsturz.

Hierfür setze ich dann AppDomain.CurrentDomain.UnhandletException ein (CF) und / oder Application.ThreadException (full .Net).

In diesen Handlern erhält der Anwender eine Nachricht, das die Software beendet werden muss und logge das Ereignis mit den Informationen über den Thrad, Exception mit InnerException und StackTrace.

Oft führt dies speziell bei der ersten Auslieferung eines Projektes zu Problemen, jedoch hatte sich seit her keine Software mehr, die sich undefiniert verhält weil irgendwo ein Fehler verschluckt wurde. Auf den CF Geräten bekomme ich so jedoch sehr Wertvolle Informationen über Probleme, die man sonst nur schwer finden kann. (Auf manchen Scannern lässt sich kein Debugger betreiben.)

Ich möchte daher Empfehlen:

Sobald man ein catch {} oder ein catch(Exception) sieht, sollte man von einem Programmierfehler ausgehen und überlegen, ob eine alles umfassende Exceptionbehandlung sinnvoll ist. Je tiefer man im Code steckt um so mehr Aufmerksamkeit sollte man solchen Gebilden schenken.

Nicht übertreiben

Im Clientcode selbst kann ein catch{} durchaus angebracht sein, denn dort lässt sich ein "undefiniertes" verhalten (relativ) einfach finden. Auch darf der Nutzen / Aufwand nicht aus dem Ruder laufen.

So bin ich bei kleiner 0815 schnell zusammenklatsch Software ein fauler Hund und fange einfach unbehandelte Ausnahmen, patsch dem Anwender eine große Messagebox mit Exception und Stacktrace entgegen und "ignoriere" den Fehler einfach. Stimmt etwas Grundlegendes nicht, meldet sich der Kunde schon und man kann das Problem beheben. Ansonsten hat der Kunde eine günstige schnellschußsoftware erhalten und kann an sich gut damit leben, das es selten mal ne MessageBox (oder MessageContainer =o) erhält.

49.485 Beiträge seit 2005
vor 15 Jahren

Hallo Knuddlbaer,

Die Kosten: Die Software endet schneller in einem Prozessabbruch.

dazu sollte man es natürlich nicht kommen lassen. Muss man aber auch nicht, denn ...

Je tiefer die Schicht des Codes ist der geschrieben wird, um so weniger sollte man überhaupt Exceptions fangen.

... heißt ja im Umkehrschluss, dass je höher die Schicht ist, desto mehr sollte man fangen. Ganz oben sollte oder muss man alles fangen.

Ich möchte die Begründung einmal an einem Praxisbeispiel, welches mir hier im Team passierte verdeutlichen.

Dazu fallen fallen mir zwei Punkte ein. Zum einen gibt es genauso Beispiele, bei denen es sich negativ auswirkt, wenn man zu wenig fängt. Du bist nun auf den umgekehrten Fall gestoßen. Das ist aber noch kein Grund, das zu verallgemeinern.

Zum anderen unterschlägst du die Möglichkeit eines Retrows der gefangenen Exception bzw. die Weitergabe derselben als InnerException einer eigenen Exception, die man am Ende der Fehlerbehandlung wirft.

Natürlich hast du recht damit, wenn du sagst:

Je tiefer man steckt, um so weniger Ahnung hat man vom Umfeld und deren Möglichkeit, auf ein Problem einzugehen.

Und genau dafür gibt es ja Exceptions, damit ein Fehler der in der Methode A auftritt zu der aufrufenden, aber entfernten Stelle C, an der er behandelt werden kann, durchgereicht werden kann. Nur ist es eben doch häufig so, dass in der Methode B, die von C aufgerufen wurde und selbst A aufruft, die Notwenigkeit besteht, darauf zu reagieren, dass in A ein Fehler aufgetreten ist. Dazu müssen die Exceptions in B gefangen werden.

Hierbei schlägt zu, was ich schon oben sagte, nämlich dass es meiner Erfahrung nach meistens egal ist, welche Exception konkret aufgetreten ist. Deshalb fange ich eben meistens alle Exceptions. Das heißt aber nicht, dass ich sie "wegfange". Wenn B den Fehler nicht vollständig beheben kann, musst natürlich auch B eine eigne Exception werfen bzw. die gefangene Exception weiterwerfen.

herbivore