# Strategien zur Behandlung von IOException gesucht



## Kalter Kaffee (5. Mai 2009)

Hallo!

Mein Programm verbindet sich als Client über TCP/IP zu einem Server und liest und schreibt Daten. Ob read und write der über Socket erreichbaren Streams bzw. readLine des darübergelegten BufferedReaders können Exceptions, insbesondere IOExceptions werfen.

Meine Frage ist nun, was mache ich damit?
Zu write steht in der API-Doku "[...] if an I/O error occurs. In particular, an IOException is thrown if the output stream is closed.", zu read "If the first byte cannot be read for any reason other than end of file, or if the input stream has been closed, or if some other I/O error occurs." oder einfach nur "If an I/O error occurs".
Es kann also zu unterschiedlichen Zeitpunkten bei unterschiedlichen mehr oder weniger spezifizierten Problemen auftreten. Bloß wie behandle ich etwas unbekanntes das alles und nichts bedeuten kann und was soll ich dem User mitteilen?

Habt ihr da Strategien dazu?

Ciao, Robert


----------



## SlaterB (5. Mai 2009)

du kannst das Programm beenden, dem User den Fehler verschweigen und einen Erfolg vorgaukeln,
die nächste Stromversorgungseinrichtung hacken um den Fehler zu vertuschen,
dem User den Fehler voller Länge anzeigen, 
eine allgemeine Fehlermeldung anzeigen mit Hinweis, dass es evtl. mit einem neuen Versuch klappen könnte usw.,

jede dieser Varianten hat seine Berechtigung, wie sollte irgendjemand anders als du selber oder dein Auftraggeber entscheiden, was nun besser ist?
das ist doch nichts, wofür es Entwurfsmuster oder sonstige Richtlinien gibt, sondern eine persönliche Entscheidung


----------



## void (5. Mai 2009)

Kalter Kaffee hat gesagt.:


> Habt ihr da Strategien dazu?



Eine allgemeine Strategie gibt es da nicht, das hängt ganz vom Anwendungsfall ab. In deinem Fall würde ich so vorgehen, tritt ein Fehler beim Verbindungsaufbau auf dann Abbruch mit Fehlermeldung "Konnte keine Verbindung herstellen".
Tritt jedoch ein Fehler während der Übertragung auf könnte man sich überlegen es einfach noch einmal oder mehrmals zu versuchen und erst nach x Fehlversuchen endgültig abzubrechen.


----------



## Kalter Kaffee (6. Mai 2009)

void hat gesagt.:


> Eine allgemeine Strategie gibt es da nicht, das hängt ganz vom Anwendungsfall ab. In deinem Fall würde ich so vorgehen, tritt ein Fehler beim Verbindungsaufbau auf dann Abbruch mit Fehlermeldung "Konnte keine Verbindung herstellen".
> Tritt jedoch ein Fehler während der Übertragung auf könnte man sich überlegen es einfach noch einmal oder mehrmals zu versuchen und erst nach x Fehlversuchen endgültig abzubrechen.



Ich habe mich wohl nicht spezifisch genug ausgedrückt.
Um einen Fehler sinnvoll zu behandeln muß ich ja wissen was er bedeutet. Eine Exception bei einem connect bedeutet sicher dass die Verbindung nicht aufgebaut werden konnte. Bei read und write klar dass nichts gelesen oder geschrieben wurde.
Was mir vor allem bei der IOException fehlt ist eine klare Information was die Konsequenz ist. So beispielsweise ob die Verbindung überhaupt nocht besteht.
Das sicherste wäre wahrscheinlich auf jede IOException im Netzwerkumfeld sicherheitshalber einen disconnect (close aller Sockets und Streams dieser Verbindung) zu machen und von vorne anzufangen. Aber vielleicht ist das auch wieder Overkill.

Zweitens wird ja propagiert Exceptions erst so weit außen wie möglich abzufangen und nicht um jeden kleinen connect, read, write usw. ein try/catch zu basteln. Nur gehen dann eben Details verloren mit denen eine Exception einem connect oder einem write zuzuschreiben wäre.

Robert


----------



## Wildcard (7. Mai 2009)

Kalter Kaffee hat gesagt.:


> Zweitens wird ja propagiert Exceptions erst so weit außen wie möglich abzufangen und nicht um jeden kleinen connect, read, write usw. ein try/catch zu basteln.


Wer propagiert das? Exceptions werden dort gefangen wo sie sinnvoll behandelt werden können.
Häufig werden spezifische Exceptions weit innen gefangen und dann allgemeinere Exceptions mit Detailinformationen nach aussen geworfen (Exception Chaining).
Der konkrete Grund für die IOException steht übrigens in der Regel in der Message. Siehe Exception#getMessage und Exception#getLocalizedMessage


----------



## Ebenius (7. Mai 2009)

Wildcard hat gesagt.:


> Wer propagiert das?


Ohne Quellenangabe und Gewähr: Als ich mich in C# eingearbeitet habe, habe ich einen Artikel aus dem Hause Microsoft gelesen, über die Entscheidung, alle Exceptions unchecked zu behandeln. Begründung war, dass der Regelfall bei der Entwicklung einer Anwendung der sei, die meisten Exceptions ohnehin an einen generischen ErrorHandler weiter zu leiten. Aus dem Grund entstünde ein unnützer Mehraufwand darin, in jeder Methode Exceptions typfein zu behandeln, weiter zu werfen, umzubauen, etc. Meiner Meinung nach ist das Unsinn und führt zu ganz vielen unerklärlichen Popups beim Benutzer; sofern es sich überhaupt um eine interaktive Anwendung handelt.

Darüber hinaus halte ich die ganze Kette der Argumentation für äußerst fragwürdig und vermute, dass die Entscheidung auf ganz anderen Grundlagen basiert; in C++ gibt's meinem schlechten Gedächtnis zu Folge keine checked Exceptions und von VB hab ich keine Ahnung. Um das ganze .NET-Framework nicht mit noch mehr Unterschieden zu belasten, entschied man sich wohl gegen checked Exceptions in C#. Aber das ist eine bloße Vermutung und Unterstellung.

... nur um mal _eine_ mögliche Quelle der Propaganda genannt zu haben ...

Ebenius


----------



## Wildcard (7. Mai 2009)

> Ohne Quellenangabe und Gewähr: Als ich mich in C# eingearbeitet habe, habe ich einen Artikel aus dem Hause Microsoft gelesen, über die Entscheidung, alle Exceptions unchecked zu behandeln


Die Diskussion checked vs. unchecked ist nicht neu und auch im Java Lager verbreitet (mit Recht), die Vertreter des unchecked Lagers sagen nicht 'soweit aussen wie möglich fangen'


----------



## Kalter Kaffee (8. Mai 2009)

Wildcard hat gesagt.:


> Wer propagiert das?


Da kann ich Dir leider keine Quellen nennen. In meinem Versuch zu lernen habe ich mehrere Bücher und Dutzende Tutorials gelesen und das ist eines der Dos die hängenblieben.



> Der konkrete Grund für die IOException steht übrigens in der Regel in der Message.


Das ist mir bewusst, nur hilft das meinem Programm bei der Entscheidung wie weiter zu verfahren ist nicht.

Robert


----------



## tfa (8. Mai 2009)

Wildcard hat gesagt.:


> Die Diskussion checked vs. unchecked ist nicht neu und auch im Java Lager verbreitet (mit Recht), die Vertreter des unchecked Lagers sagen nicht 'soweit aussen wie möglich fangen'



Richtig. Checked Exceptions sind Käse. C# hat Glück gehabt, dass die nicht von Java abgekupfert wurden. 


> [...]Meiner Meinung nach ist das Unsinn und führt zu ganz vielen unerklärlichen Popups beim Benutzer;


Nur wenn man sie alle nach oben durch reicht, was man nicht immer tun sollte. Unchecked Exception verbieten ja nicht, dass man sie fängt und behandelt.

Checked Exceptions machen (wenn überhaupt) nur Sinn in geschlossen Anwendungen und nicht in APIs, Libs oder Frameworks.

@TS: Der Tip mit dem Reconnect-Versuch war doch gar nicht so schlecht.


----------



## Ebenius (8. Mai 2009)

Ohje, ich wollte doch keinen Glaubenskrieg anfangen/weiterführen.  Ich mag checked Exceptions, aber das ist auch nur Glaubenssache.

Ebenius


----------



## sliwalker (8. Mai 2009)

Hi,

der angesprochene Artikel ist von Krzysztof Cwalina, unter anderem Program Manager des Bereichen CRL.
Der Titel ist mir entfallen, aber sollte nicht so schwer zu finden sein. In seinem Buch "Richtlinien für das Framework-Design" spricht er dieses Thema auch an und bringt eine schlüssige, wenngleich zu verallgemeinerte Argumentation vor.

Ich halte mich an das prinzip Exceptions nicht möglich weit aussen zu fangen, sondern "nur eine Exception zu fangen, wenn ich einen guten Grund dazu habe". Das wäre für mich loggen, Userinformationen ausgeben oder auch die verarbeitung nicht abbrechen zu lassen, wenn noch Daten verarbeitet werden müssen.
Ein beispiel sind da immer wieder csv-Reader, die Daten abgleichen müssen, wenn die Schleife abbricht, wurden nicht alle Daten versucht zu importieren, nur weil der erste Datensatz Mist war.

Die Ungenauigkeit der IOException kannst Du verändern, indem Du Dir eine eigene Exception-Hierachie schreibst und entsprechend fängst und wirfst. Es steht Dir frei das so detailliert zu machen wie Du möchtest. Schon daran gedacht? Ohne selbst entwickelte Exceptions wird es wahrlich schwer zu granulieren. Man denke an einen Finanzprozess, bei dem x Dinge schief gehen können. Einfach nur eine BusinessException zu schmeißen reicht da nicht aus. Bei manchen muss die Trasaktion zurück gerollt werden, bei manchen ein Dialog angezeigt werden und manche werden einfach nur gelogged.

Der grund warum nicht immer da fangen soll, wo der Fehler auftritt ist ganz einfach der, zumindest für mich, dass man das DRY-Prinzip nicht verletzen sollte. Dont repeat yourself. Andernfalls schreibst Du tausendfach denselben Code zur Fehlerbehandlung, den Du im Falle einer großen Änderung auch tausendfach ändern musst.

Und warum dieser Ansatz gut sein kann zeigt die aspektorientierte Programmierung, wo Du Fehler durch Annotations an die richtige Stelle lenkst.

greetz
SLi


----------



## tfa (8. Mai 2009)

> Ohje, ich wollte doch keinen Glaubenskrieg anfangen/weiterführen.  Ich mag checked Exceptions, aber das ist auch nur Glaubenssache.



Ich lerne sie gerade hassen. Auf dem Server (keine User-Interaktion) , wo ich gerade entwickele, sind sie nutzlos. Gut, dass Hibernate sie angeschafft hat und Spring gar nicht erst eingeführt.


----------

