it-swarm.com.de

Warum ist der Fang (Ausnahme) fast immer eine schlechte Idee?

Warum ist die catch(Exception) fast immer eine schlechte Idee?

51
Nasser Hadjloo

Denn wenn Sie die Ausnahmebedingung Sie sollen es richtig behandeln fangen. Und Sie können nicht erwarten, alle Arten von Ausnahmen in Ihrem Code zu behandeln. Wenn Sie alle Ausnahmen abfangen, erhalten Sie möglicherweise eine Ausnahme, die nicht mit Code umgehen kann, der höher ist, um eine ordnungsgemäße Verarbeitung zu gewährleisten.

Das generelle Prinzip ist, den spezifischsten Typ zu erfassen, den Sie können. 

52
anthares

Kurzgeschichte: Es heißt Bug Masking. Wenn Sie einen Code haben, der nicht gut funktioniert und Ausnahmen auslöst (oder Sie missgebildete Eingaben an diesen Code übergeben) und Sie Ihre Augen blenden, indem Sie alle möglichen Ausnahmen fangen, werden Sie den Fehler eigentlich nie aufdecken und beheben.

18
dimitarvp

Ausnahmen sollten Sie nur erwischen, wenn Sie sie richtig handhaben können. Da Sie nicht alle möglichen Ausnahmen richtig behandeln können, sollten Sie sie nicht fangen :-)

8
Darin Dimitrov

Weil Sie nicht wirklich wissen, warum eine Ausnahme aufgetreten ist, und mehrere Ausnahmen erfordern, dass sehr spezielles Fahrzeug (wenn überhaupt möglich) korrekt gehandhabt wird, z. B. eine OutOfMemoryException und ähnliche Low-Level-Systemausnahmen.

Daher sollten Sie nur Ausnahmen feststellen:

  • sie wissen genau, wie Sie damit umgehen sollen (z. B. FileNotFoundException oder so).
  • wenn Sie sie danach erneut erhöhen (z. B. um eine Bereinigung nach einem Fehler durchzuführen)
  • wenn Sie die Ausnahme in einen anderen Thread transportieren müssen
5
Lucero

Es hängt davon ab, was Sie brauchen. Wenn Sie verschiedene Arten von Ausnahmen auf unterschiedliche Weise behandeln müssen, sollten Sie mehrere catch-Blöcke verwenden und so viele spezifische Ausnahmen wie möglich abfangen. 

Aber manchmal müssen Sie alle Ausnahmen auf dieselbe Weise behandeln. In solchen Fällen kann catch (Ausnahme) in Ordnung sein. Zum Beispiel:

    try
    {
        DoSomething();
    }
    catch (Exception e)
    {
        LogError(e);
        ShowErrorMessage(e); // Show "unexpected error ocurred" error message for user.
    }
4
Andrew Bezzub

Ich finde zwei Verwendungsmöglichkeiten von catch(Exception):

  • Auf der obersten Ebene der Anwendung (kurz vor dem Zurückkehren zum Benutzer). Auf diese Weise können Sie eine adäquate Nachricht senden.
  • Verwenden Sie es, um Low-Level-Ausnahmen als geschäftliche auszublenden.

Der erste Fall ist selbsterklärend, aber lassen Sie mich den zweiten Fall entwickeln:

Tun:

try {
    // xxxx
} catch(Exception e) {
    logger.error("Error XXX",e)
}

bug Masking wie @dimitarvp gesagt.

Das Folgende ist jedoch anders:

try {
    // xxxx
} catch(Exception e) {
    throw new BussinessException("Error doing operation XXX",e)
}

Auf diese Weise ignoriert man keine Fehler und versteckt sie unter dem Teppich. Sie bieten eine übergeordnete Ausnahme mit einer erklärenden Nachricht an höhere Anwendungsebenen.

Es ist auch immer wichtig, Ausnahmen auf der richtigen Ebene zu verwalten. Wenn Sie eine Low-Level-Ausnahme auf eine High-Business-Ebene umleiten, ist es für die höhere Ebene praktisch unmöglich, sie gut zu verwalten.

In diesem Fall ziehe ich es vor, die niedrigen Ausnahmen mit einem geschäftlichen zu maskieren, das einen besseren Kontext und eine bessere Nachricht liefert und außerdem die ursprüngliche Ausnahme enthält, um in die Details eingehen zu können.

Wenn Sie konkretere Ausnahmen finden und diese besser behandeln können, müssen Sie dies tun.

Wenn Sie in einem Codeblock eine SQLException und eine NetworkException erhalten können, müssen Sie sie abfangen und für jeden von ihnen eine angemessene Meldung und Behandlung bereitstellen. Wenn Sie jedoch am Ende des try/catch-Blocks eine Exception-Zuordnung haben es ist eine BussinessException, es ist für mich in Ordnung. Tatsächlich finde ich es angemessen, wenn höhere Serviceebenen nur Business-Ausnahmen werfen (mit Details im Inneren).

3
lujop

Außer was noch @anthares beantwortet hat:

Denn wenn Sie die Ausnahmebedingung Sie sollen es richtig behandeln fangen. Und Sie können nicht erwarten, alle Arten von Ausnahmen in Ihrem Code zu behandeln. Wenn Sie alle Ausnahmen abfangen, erhalten Sie möglicherweise eine Ausnahme, die nicht mit Code umgehen kann, der höher ist, um eine ordnungsgemäße Verarbeitung zu gewährleisten.

Das generelle Prinzip ist, den spezifischsten Typ zu erfassen, den Sie können.

catch(Exception) ist eine schlechte Praxis, da auch alle RuntimeException (ungeprüfte Ausnahme) abgefangen werden.

1
taringamberini

Aber manchmal ist es OK! Zum Beispiel, wenn Sie einen Code haben, der etwas „Extraes“ macht, was Ihnen wirklich egal ist, und Sie möchten nicht, dass Ihre Anwendung dadurch in die Luft gejagt wird. Ich habe zum Beispiel kürzlich an einer großen Anwendung gearbeitet, bei der unsere Geschäftspartner eine bestimmte tägliche Transaktion in einer neuen Protokolldatei zusammenfassen wollten. Sie erklärten, dass das Logbuch für sie nicht so wichtig sei und nicht als Anforderung zu qualifizieren sei. Es war nur etwas Besonderes, das ihnen helfen würde, die verarbeiteten Daten zu verstehen. Sie brauchten es nicht, weil sie die Informationen woanders bekommen konnten. Das ist also ein seltener Fall, in dem es vollkommen in Ordnung ist, Ausnahmen zu fangen und zu schlucken.

Ich habe auch in einer Firma gearbeitet, in der alle Throwables abgefangen und dann innerhalb einer benutzerdefinierten RuntimeException neu erstellt wurden. Ich würde dieses Vorgehen nicht empfehlen, sondern nur darauf hinweisen, dass es getan wird.

0
MattC

Dies kann Java-spezifisch sein:

Manchmal müssen Sie Methoden aufrufen, die geprüfte Ausnahmen auslösen. Wenn dies in Ihrer EJB/Geschäftslogik-Schicht ist, haben Sie zwei Möglichkeiten - fangen Sie sie oder werfen Sie sie erneut. 

Wenn bestimmte Ausnahmeklassen abgefangen werden, müssen Sie Ihre Aktionen erneut analysieren, für die Ausnahmen ausgelöst werden können, wenn Sie sehen, wie dieser Code mit Ausnahmen behandelt. Sie werden oft in eine "Was wäre, wenn ..." - Situation geraten, und es kann eine große Anstrengung sein, nur zu klären, ob Ausnahmen korrekt behandelt werden.

Erneutes Werfen bedeutet, dass der Code, der Ihre EJBs anruft, mit fangendem Code übersät ist, der der aufrufenden Klasse normalerweise nichts bedeutet. n.b. Das Auslösen von geprüften Ausnahmen von EJB-Methoden bedeutet, dass Sie für das manuelle Zurücksetzen von Transaktionen verantwortlich sind.

0

Ist es nicht ein anderes gültiges Szenario, um sicherzustellen, dass ein Thread Ausnahmen in seinem Inneren auffängt?

Thread shouldRunWhenApplicationRuns = new Thread() {
    @Override
    public void run() {
        try {
            // do something that should never end
        } catch (Exception ex) {
            // log it
        }
    };
    shouldRunWhenApplicationRuns.start();
0
opfau