Ich habe an einer Android-App gearbeitet, die try/catch
häufig verwendet wird, um zu verhindern, dass sie selbst an Orten abstürzt, an denen keine Notwendigkeit besteht. Zum Beispiel,
Eine Ansicht in xml layout
mit id = toolbar
wird wie folgt referenziert:
// see new example below, this one is just confusing
// it seems like I am asking about empty try/catch
try {
View view = findViewById(R.id.toolbar);
}
catch(Exception e) {
}
Dieser Ansatz wird in der gesamten App verwendet. Die Stapelverfolgung wird nicht gedruckt und es ist wirklich schwer zu finden, was schief gelaufen ist. Die App wird plötzlich geschlossen, ohne dass eine Stapelverfolgung gedruckt werden muss.
Ich bat meinen Senior, es mir zu erklären, und er sagte:
Dies dient dazu, Abstürze in der Produktion zu verhindern.
Ich bin damit überhaupt nicht einverstanden . Für mich ist dies nicht der Weg, um Apps vor Abstürzen zu schützen. Es zeigt, dass der Entwickler nicht weiß, was er tut, und Zweifel hat.
Wird dieser Ansatz in der Industrie verwendet, um Abstürze von Unternehmensanwendungen zu verhindern?
Wenn try/catch
es wirklich, wirklich unser Bedürfnis ist, ist es dann möglich, einen Ausnahmebehandler mit UI-Thread oder anderen Threads anzuhängen und dort alles abzufangen? Das wird nach Möglichkeit ein besserer Ansatz sein.
Ja, leer try/catch
ist schlecht, und selbst wenn wir eine Stapelverfolgung oder eine Protokollausnahme auf dem Server drucken try/catch
, ist es für mich nicht sinnvoll , Codeblöcke zufällig über die gesamte App zu verpacken , z. B. wenn jede Funktion in a eingeschlossen ist try/catch
.
AKTUALISIEREN
Da diese Frage viel Aufmerksamkeit erhalten hat und einige Leute die Frage falsch interpretiert haben (vielleicht weil ich sie nicht klar formuliert habe), werde ich sie umformulieren.
Hier ist, was Entwickler hier tun
Eine Funktion wird geschrieben und getestet . Es kann sich um eine kleine Funktion handeln, die nur Ansichten initialisiert, oder um eine komplexe Funktion. Nach dem Testen wird sie um einen
try/catch
Block gewickelt . Auch für Funktionen, die niemals eine Ausnahme auslösen.Diese Vorgehensweise wird in der gesamten Anwendung angewendet. Manchmal wird eine Stapelverfolgung gedruckt und manchmal nur eine
debug log
zufällige Fehlermeldung. Diese Fehlermeldung unterscheidet sich von Entwickler zu Entwickler.Bei diesem Ansatz stürzt die App nicht ab, aber das Verhalten der App wird unbestimmt. Selbst manchmal ist es schwer zu verfolgen, was schief gelaufen ist.
Die eigentliche Frage, die ich gestellt habe, war: Ist es in der Branche üblich, zu verhindern, dass Unternehmensanwendungen abstürzen? und ich frage nicht nach leerem try / catch . Ist es so, dass Benutzer Anwendungen lieben, die nicht abstürzen, als Anwendungen, die sich unerwartet verhalten? Weil es wirklich darauf ankommt, es entweder zum Absturz zu bringen oder dem Benutzer einen leeren Bildschirm anzuzeigen oder das Verhalten des Benutzers nicht zu bemerken.
Ich poste hier ein paar Ausschnitte aus dem echten Code
private void makeRequestForForgetPassword() { try { HashMap<String, Object> params = new HashMap<>(); String email= CurrentUserData.msisdn; params.put("email", "blabla"); params.put("new_password", password); NetworkProcess networkProcessForgetStep = new NetworkProcess( serviceCallListenerForgotPasswordStep, ForgotPassword.this); networkProcessForgetStep.serviceProcessing(params, Constants.API_FORGOT_PASSWORD); } catch (Exception e) { e.printStackTrace(); } } private void languagePopUpDialog(View view) { try { PopupWindow popupwindow_obj = popupDisplay(); popupwindow_obj.showAsDropDown(view, -50, 0); } catch (Exception e) { e.printStackTrace(); } } void reloadActivity() { try { onCreateProcess(); } catch (Exception e) { } }
Es handelt sich nicht um ein Duplikat der Best Practices für die Behandlung von Android-Ausnahmen . Dort versucht OP, Ausnahmen für einen anderen Zweck als diese Frage abzufangen.
quelle
catch(Exception e){}
- dieser Kommentar machte vor der Bearbeitung der Frage SinnON ERROR RESUME NEXT
Antworten:
Natürlich gibt es immer Ausnahmen von Regeln, aber wenn Sie eine Faustregel benötigen, dann sind Sie richtig; leere Fangblöcke sind "absolut" schlechte Praxis.
Schauen wir uns das genauer an und beginnen wir mit Ihrem konkreten Beispiel:
try { View view = findViewById(R.id.toolbar); } catch(Exception e) { }
So wird ein Verweis auf etwas erstellt; und wenn das fehlschlägt ... spielt es keine Rolle; weil diese Referenz überhaupt nicht verwendet wird! Der obige Code ist absolut nutzloses Leitungsrauschen . Oder geht die Person, die diesen Code geschrieben hat, zunächst davon aus, dass ein zweiter, ähnlicher Aufruf auf magische Weise keine Ausnahme mehr auslösen würde?!
Vielleicht sollte das so aussehen:
try { View view = findViewById(R.id.toolbar); ... and now do something with that view variable ... } catch(Exception e) { }
Aber was hilft das wieder?! Es gibt Ausnahmen, um Fehlersituationen in Ihrem Code zu kommunizieren bzw. zu verbreiten . Das Ignorieren von Fehlern ist selten eine gute Idee. Tatsächlich kann eine Ausnahme folgendermaßen behandelt werden:
Lange Rede kurzer Sinn: die Mindeste, was Sie mit einer Ausnahme tun, ist, sie zu protokollieren / zu verfolgen. Wenn Sie später ein Problem debuggen, verstehen Sie "OK, zu diesem Zeitpunkt ist diese Ausnahme aufgetreten".
Und wie andere bereits betont haben: Sie vermeiden es auch, generell nach Ausnahmen zu suchen (je nach Ebene: Es kann gute Gründe geben, Ausnahmen zu fangen und sogar einige Arten von Fehlern auf höchster Ebene, um dies sicherzustellen nichts geht verloren; niemals ).
Zum Schluss zitieren wir Ward Cunningham :
Sie wissen, dass Sie mit sauberem Code arbeiten, wenn sich herausstellt, dass jede Routine, die Sie lesen, ziemlich genau Ihren Erwartungen entspricht. Sie können es als schönen Code bezeichnen, wenn der Code auch den Eindruck erweckt, dass die Sprache für das Problem erstellt wurde.
Lass das einwirken und meditiere darüber. Sauberer Code ist nicht überraschen. Das Beispiel, das Sie uns zeigen, überrascht alle ansehen.
Update bezüglich des Updates, nach dem das OP fragt
try { do something } catch(Exception e) { print stacktrace }
Gleiche Antwort: Das "überall" zu tun ist auch eine schlechte Praxis. Weil dieser Code auch ist überraschend die Leser.
Obenstehendes:
Verwenden Sie also try / catch als "Muster", wie Sie es zeigen. ist wie gesagt: immer noch keine gute idee. Und ja, es verhindert Abstürze; führt aber zu allen Arten von "undefiniertem" Verhalten. Sie wissen, wenn Sie nur eine Ausnahme abfangen, anstatt sie richtig zu behandeln. Sie öffnen eine Dose Würmer; weil Sie in Myriaden führen könnten Folge auf Fehler , die Sie später nicht verstehen. Weil Sie das Ereignis "Grundursache" früher konsumiert haben; druckte es irgendwo; und das irgendwo ist jetzt weg.
quelle
Aus der Android-Dokumentation :
Nennen wir es als -
Formatierung / Absatz leicht geändert von der Quelle für diese Antwort.
PS Hab keine Angst vor Ausnahmen !! Sie sind Freunde!!!
quelle
Object a; try { a = thing(); } catch (Exception e) {...} try { a.action(); } catch (Exception e) {...}
))Exception
könnte das Fangen von Generika als Teil eines "Log-before-Crashing" -Systems nützlich sein, obwohl es in diesem Fall neu geworfen werden sollte.Ich würde dies als Kommentar zu einer anderen Antwort setzen, aber dafür habe ich noch keinen Ruf.
Sie sagen zu Recht, dass es sich um eine schlechte Praxis handelt. In der Tat zeigt das, was Sie veröffentlicht haben, verschiedene Arten von schlechten Praktiken in Bezug auf Ausnahmen.
Ich werde versuchen, all dies anhand dieses Beispiels zu erklären.
try { User user = loadUserFromWeb(); if(user.getCountry().equals("us")) { enableExtraFields(); } fillFields(user); } catch (Exception e) { }
Dies kann auf verschiedene Arten fehlschlagen, die unterschiedlich gehandhabt werden sollten.
Lösungen
(1) Zuallererst ist es keine gute Sache, lautlos zu versagen. Wenn ein Fehler auftritt, funktioniert die App nicht. Stattdessen sollte versucht werden, das Problem zu beheben, oder eine Warnung angezeigt werden, z. B. "Benutzerdaten konnten nicht geladen werden, möglicherweise sind Sie nicht mit dem Internet verbunden?". Wenn die App nicht das tut, was sie soll, ist das für einen Benutzer viel frustrierender, als wenn sie sich einfach selbst schließt.
(4) Wenn der Benutzer unvollständig ist, z. B. das Land nicht bekannt ist und null zurückgibt. Die equals-Methode erstellt eine NullPointerException. Wenn diese NPE wie oben geworfen und abgefangen wird, wird die Methode fillFields (Benutzer) nicht aufgerufen, obwohl sie weiterhin problemlos ausgeführt werden kann. Sie können dies verhindern, indem Sie Nullprüfungen einschließen, die Ausführungsreihenfolge ändern oder den Try / Catch-Bereich anpassen. (Oder Sie könnten die Codierung wie folgt speichern: "us" .equals (user.getCountry ()), aber ich musste ein Beispiel angeben). Natürlich verhindert jede andere Ausnahme auch die Ausführung von fillFields (), aber wenn kein Benutzer vorhanden ist, möchten Sie wahrscheinlich nicht, dass es trotzdem ausgeführt wird.
(1, 2, 3) Beim Laden aus dem Web werden häufig verschiedene Ausnahmen ausgelöst, von der IOException über die Ausnahme HttpMessageNotReadable bis hin zur Rückkehr. Möglicherweise ist der Benutzer nicht mit dem Internet verbunden, möglicherweise wurde ein Backend-Server geändert oder er ist ausgefallen, aber Sie wissen es nicht, weil Sie abfangen (Ausnahme). Stattdessen sollten Sie bestimmte Ausnahmen abfangen. Sie können sogar mehrere davon so fangen
try{ User user = loadUserFromWeb(); //throws NoInternetException, ServerNotAvailableException or returns null if user does not exist if(user == null) { throw new UserDoesNotExistException(); //there might be better options to solve this, but it highlights how exceptions can be used. } fillFields(user); if("us".equals(user.getCountry()) { enableExtraFields(); } } catch(NoInternetException e){ displayWarning("Your internet conneciton is down :("); } catch(ServerNotAvailableException e){ displayWarning("Seems like our server is having trouble, try again later."); } catch(UserDoesNotExistException e){ startCreateUserActivity(); }
Ich hoffe das erklärt es.
Zumindest als schnelle Lösung können Sie mit Ausnahme eines Ereignisses ein Ereignis an Ihr Backend senden. Zum Beispiel durch Firebase oder Crashlytics. Auf diese Weise können Sie zumindest Dinge wie (hey, die Hauptaktivität wird für 80% unserer Benutzer aufgrund eines Problems wie (4) nicht geladen.
quelle
Es ist definitiv eine schlechte Programmierpraxis.
Aus dem aktuellen Szenario, wenn es Hunderte von gibt
try
catch
davon gibt, wissen Sie nicht einmal, wo die Ausnahme auftritt, ohne die Anwendung zu debuggen. Dies ist ein Albtraum, wenn sich Ihre Anwendung in einer Produktionsumgebung befindet.Sie können jedoch einen Logger einbinden, damit Sie wissen, wann eine Ausnahme ausgelöst wird (und warum). Es wird Ihren normalen Workflow nicht ändern.
... try { View view = findViewById(R.id.toolbar); }catch(Exception e){ logger.log(Level.SEVERE, "an exception was thrown", e); } ...
quelle
Das ist schlechte Praxis. Andere Antworten haben das gesagt, aber ich denke, es ist wichtig, zurückzutreten und zu verstehen, warum wir überhaupt Ausnahmen haben.
Jede Funktion hat eine Nachbedingung - eine Reihe von Dingen, die alle wahr sein müssen, nachdem diese Funktion ausgeführt wurde. Beispielsweise hat eine Funktion, die aus einer Datei liest, die Post-Bedingung, dass die Daten in der Datei von der Festplatte gelesen und zurückgegeben werden. Eine Ausnahme wird dann ausgelöst, wenn eine Funktion eine ihrer Nachbedingungen nicht erfüllen konnte.
Indem Sie eine Ausnahme von einer Funktion ignorieren (oder sie sogar effektiv ignorieren, indem Sie einfach die Ausnahme protokollieren), sagen Sie, dass Sie mit dieser Funktion einverstanden sind, wenn Sie nicht die gesamte Arbeit erledigen, für die sie sich bereit erklärt hat. Dies scheint unwahrscheinlich - wenn eine Funktion nicht korrekt ausgeführt wird, gibt es keine Garantie dafür, dass das Folgende überhaupt ausgeführt wird. Und wenn der Rest Ihres Codes einwandfrei funktioniert, unabhängig davon, ob eine bestimmte Funktion vollständig ausgeführt wird oder nicht, fragt man sich, warum Sie diese Funktion überhaupt haben.
[Jetzt gibt es bestimmte Fälle, in denen leere
catch
es in Ordnung sind. Zum Beispiel ist die Protokollierung etwas, das Sie möglicherweise rechtfertigen, wenn Sie einen leeren Fang einschließen. Ihre Anwendung wird wahrscheinlich auch dann einwandfrei ausgeführt, wenn ein Teil der Protokollierung nicht geschrieben werden kann. Aber das sind Sonderfälle, bei denen man wirklich hart arbeiten muss, um sie in einer normalen App zu finden.]Der Punkt ist also, dass dies eine schlechte Praxis ist, da Ihre App dadurch nicht weiter ausgeführt wird (die angebliche Rechtfertigung für diesen Stil). Vielleicht hat das Betriebssystem es technisch nicht getötet. Es ist jedoch unwahrscheinlich, dass die App nach einfachem Ignorieren einer Ausnahme noch ordnungsgemäß ausgeführt wird. Und im schlimmsten Fall kann es tatsächlich Schaden anrichten (z. B. Beschädigung von Benutzerdateien usw.).
quelle
Dies ist aus mehreren Gründen schlecht:
findViewById
eine Ausnahme auslöst? Beheben Sie das (und sagen Sie mir, weil ich das noch nie gesehen habe), anstatt es zu fangen.Exception
Sie wenn Sie eine bestimmte Art von Ausnahme könnten.Wenn eine App in einen schlechten Zustand gerät, ist es viel besser, wenn sie abstürzt, als wenn sie in ihrem unbrauchbaren Zustand tuckert. Wenn man eine NPE sieht, sollte man nicht einfach einen Null-Check machen und weggehen. Der bessere Ansatz besteht darin, herauszufinden, warum etwas null ist, und entweder zu verhindern, dass es null ist, oder (wenn null ein gültiger und erwarteter Zustand ist) nach null zu suchen. Sie müssen jedoch verstehen, warum das Problem überhaupt auftritt.
quelle
Ich habe in den letzten 4-5 Jahren Android-Apps entwickelt und nie einen Try-Catch für die Ansichtsinitialisierung verwendet.
Wenn es eine Symbolleiste ist, machen Sie das so
Beispiel: - Um eine Textansicht aus einer Ansicht abzurufen (Fragment / Dialog / eine benutzerdefinierte Ansicht)
TextView textview = (TextView) view.findViewById (R.id.viewId);
an Stelle von
Ein Ansichtsobjekt hat im Vergleich zu seinem tatsächlichen Ansichtstyp eine minimale Reichweite.
Hinweis: - Möglicherweise ist es abgestürzt, weil die Ansicht geladen wurde. Das Hinzufügen von Try Catch ist jedoch eine schlechte Praxis.
quelle
View
können und die bereits nützlich sein können (wiesetVisibility()
), ohne dass Sie genau angeben, welche Klasse verwendet wird. (Zum Beispiel im Fall eines Layouts, das von Zeit zu Zeit geändert werden kann)Ja, try / catch wird verwendet, um einen Absturz der App zu verhindern, aber Sie benötigen try / catch sicherlich nicht, um eine Ansicht aus XML abzurufen, wie in Ihrer Frage dargestellt.
try / catch wird im Allgemeinen verwendet, wenn Sie eine http-Anfrage stellen, einen String in eine URL analysieren, URL-Verbindungen erstellen usw. und sicherstellen, dass die Stapelverfolgung gedruckt wird. Wenn Sie es nicht drucken, macht es wenig Sinn, es mit try / catch zu umgeben.
quelle
Wie bereits erwähnt, sollten allgemeine Ausnahmen nicht oder nur in wenigen Fällen abgefangen werden zentralen Stellen (normalerweise im Framework- / Infrastrukturcode, nicht im Anwendungscode). Wenn allgemeine Ausnahmen abgefangen und protokolliert werden, sollte die Anwendung anschließend heruntergefahren werden, oder zumindest sollte der Benutzer darüber informiert werden, dass sich die Anwendung möglicherweise in einem instabilen Zustand befindet und Daten beschädigt werden können (wenn der Benutzer die Ausführung fortsetzt). Denn dies kann passieren, wenn Sie alle Arten von Ausnahmen abfangen (nicht genügend Speicher, um nur eine zu nennen) und die App in einem undefinierten Zustand belassen.
IMHO ist es schlimmer, Ausnahmen zu schlucken und Datenintegrität, Datenverlust oder einfach das Verlassen der App in einem undefinierten Zustand zu riskieren, als die App abstürzen zu lassen und der Benutzer weiß, dass etwas schief gelaufen ist und kann es erneut versuchen. Dies führt auch zu besseren gemeldeten Problemen (mehr an der Wurzel des Problems), wahrscheinlich weniger unterschiedlichen Symptomen, als wenn Ihre Benutzer anfangen, alle Arten von Problemen zu melden, die vom undefinierten Anwendungsstatus herrühren.
Beginnen Sie nach einer zentralen Ausnahmebehandlung / Protokollierung / Berichterstellung und einem kontrollierten Herunterfahren mit dem Umschreiben der Ausnahmebehandlung, um lokale Ausnahmen so spezifisch wie möglich zu erfassen. Versuchen Sie, den try {} -Block so kurz wie möglich zu halten.
quelle
Lassen Sie mich meinen Standpunkt hinzufügen, als ein Mann, der seit mehr als einem Jahrzehnt in der mobilen Entwicklungsbranche von Unternehmen tätig ist. Zunächst einige allgemeine Tipps zu Ausnahmen, von denen die meisten in den obigen Antworten enthalten sind:
Wenn Sie jetzt keine App für sich selbst entwickeln, sondern für ein Unternehmen oder eine Firma, müssen Sie häufig zusätzliche Anforderungen zu diesem Thema stellen:
Die kurze Antwort lautet also, dass der Code, den Sie gefunden haben, kein Beispiel für eine gute Praxis ist, da die Wartung schwierig und kostspielig ist, ohne die Qualität der App zu verbessern.
quelle
Eine andere Perspektive: Als jemand, der täglich Unternehmenssoftware schreibt, möchte ich, dass eine App abstürzt , wenn sie einen nicht behebbaren Fehler aufweist . Absturz ist wünschenswert. Wenn es abstürzt, wird es protokolliert. Wenn es in kurzer Zeit mehr als ein paar Mal abstürzt, erhalte ich eine E-Mail mit dem Hinweis, dass die App abstürzt, und ich kann überprüfen, ob unsere App und alle von uns genutzten Webdienste noch funktionieren.
Also die Frage:
Ist
try{ someMethod(); }catch(Exception e){}
gute Übung? Nein! Hier sind einige Punkte:
Das Wichtigste: Dies ist eine schlechte Kundenerfahrung. Woher soll ich wissen, wenn etwas Schlimmes passiert? Meine Kunden versuchen, meine App zu verwenden, und nichts funktioniert. Sie können ihr Bankkonto nicht überprüfen, ihre Rechnungen nicht bezahlen, was auch immer meine App tut. Meine App ist völlig nutzlos, aber hey, zumindest ist sie nicht abgestürzt! (Ein Teil von mir glaubt, dass dieser "ältere" Entwickler Brownie-Punkte für niedrige Crash-Zahlen bekommt, also spielen sie das System.)
Wenn ich entwickle und schlechten Code schreibe, wenn ich nur alle Ausnahmen auf der obersten Ebene abfange und verschlucke, habe ich keine Protokollierung. Ich habe nichts in meiner Konsole und meine App schlägt lautlos fehl. Soweit ich das beurteilen kann, scheint alles in Ordnung zu sein. Also habe ich den Code festgeschrieben ... Es stellte sich heraus, dass mein DAO-Objekt die ganze Zeit über null war und die Zahlungen des Kunden in der Datenbank nie aktualisiert wurden. Hoppla! Aber meine App ist nicht abgestürzt, das ist also ein Plus.
Nehmen wir an, ich war damit einverstanden, jede Ausnahme zu fangen und zu schlucken. Es ist extrem einfach , einen benutzerdefinierten Ausnahmebehandler in Android zu schreiben. Wenn Sie wirklich nur haben jede Ausnahme zu fangen, können Sie es an einem Ort tun und nicht Pfeffer
try/catch
ganzen Code - Basis.Einige der Entwickler, mit denen ich in der Vergangenheit zusammengearbeitet habe, haben den Absturz für schlecht gehalten.
Ich muss ihnen versichern, dass unsere App abstürzen soll. Nein, eine instabile App ist nicht in Ordnung, aber ein Absturz bedeutet, dass wir etwas falsch gemacht haben und es beheben müssen. Je schneller es abstürzt, je früher wir es finden, desto einfacher ist es zu beheben. Die einzige andere Option, die ich mir vorstellen kann, besteht darin, dem Benutzer zu erlauben, in einer unterbrochenen Sitzung fortzufahren, was ich mit dem Verärgern meiner Benutzerbasis gleichsetze.
quelle
Es ist eine schlechte Praxis
catch(Exception e){}
weil Sie den Fehler im Wesentlichen ignorieren. Was Sie wahrscheinlich tun möchten, ist eher so etwas wie:try { //run code that could crash here } catch (Exception e) { System.out.println(e.getMessage()); }
quelle
Wir verwenden so ziemlich dieselbe Logik. Verwenden
try-catch
diese , um zu verhindern, dass Produktions-Apps abstürzen.Ausnahmen sollten NIE sein ignoriert werden. Es ist eine schlechte Codierungspraxis. Die Leute, die den Code pflegen, werden es wirklich schwer haben, den Teil des Codes zu lokalisieren, der die Ausnahme ausgelöst hat, wenn sie nicht protokolliert sind.
Wir verwenden
Crashlytics
, um die Ausnahmen zu protokollieren. Der Code stürzt nicht ab (einige Funktionen werden jedoch unterbrochen). Sie erhalten jedoch das Ausnahmeprotokoll im Dashboard vonFabric/Crashlytics
. Sie können sich diese Protokolle ansehen und die Ausnahmen beheben.try { codeThatCouldRaiseError(); } catch (Exception e) { e.printStackTrace(); Crashlytics.logException(e); }
quelle
Obwohl ich den anderen Antworten zustimme, habe ich wiederholt einen Umstand festgestellt, bei dem dieses Motiv nur geringfügig tolerierbar ist. Angenommen, jemand hat ein bisschen Code für eine Klasse wie folgt geschrieben:
private int foo=0; . . . public int getFoo() throws SomeException { return foo; }
Unter diesen Umständen kann die Methode 'getFoo ()' nicht fehlschlagen. Es wird immer ein legitimer Wert des privaten Felds 'foo' zurückgegeben. Dennoch hat jemand - wahrscheinlich aus pedantischen Gründen - entschieden, dass diese Methode als potenziell auslösend deklariert werden sollte. Wenn Sie dann versuchen, diese Methode in einem Kontext aufzurufen - z. B. einem Ereignishandler -, in dem keine Ausnahme ausgelöst werden kann, müssen Sie dieses Konstrukt grundsätzlich verwenden (selbst dann stimme ich zu, dass man zumindest die Ausnahme nur protokollieren sollte falls) . Wann immer ich dies tun muss, füge ich neben der 'catch'-Klausel mindestens einen großen, fetten Kommentar hinzu: "DAS KANN NICHT AUFTRETEN".
quelle