Waarom is de Catch(Exception) bijna altijd een slecht idee?

Waarom is de catch(Exception)bijna altijd een slecht idee?


Antwoord 1, autoriteit 100%

Omdat wanneer je een uitzondering opmerkt je geacht wordt deze op de juiste manier af te handelen. En je kunt niet verwachten dat je allerlei uitzonderingen in je code kunt verwerken. Ook wanneer u alle uitzonderingen opvangt, kunt u een uitzondering krijgen die niet kan omgaan met en voorkomen dat code die zich bovenaan de stapel bevindt, deze correct afhandelt.

Het algemene principe is om het meest specifieke type te vangen dat je kunt.


Antwoord 2, autoriteit 31%

Kort verhaal: het wordt bugmaskering genoemd. Als je een stuk code hebt dat niet goed werkt en uitzonderingen genereert (of je geeft verkeerd gevormde invoer door aan dat stuk code) en je verblindt je ogen door alle mogelijke uitzonderingen op te vangen, je zult de bug eigenlijk nooit ontdekken en repareren.


Antwoord 3, autoriteit 12%

Je mag alleen uitzonderingen opvangen als je ze goed kunt afhandelen. Omdat je niet alle mogelijke uitzonderingen goed kunt verwerken, moet je ze niet vangen 🙂


Antwoord 4, autoriteit 6%

Omdat je niet echt weet waarom er een uitzondering is opgetreden, en voor verschillende uitzonderingen moet een heel speciale auto correct worden afgehandeld (indien mogelijk), zoals een OutOfMemoryException en soortgelijke systeemuitzonderingen op laag niveau.

Daarom moet je alleen uitzonderingen opvangen:

  • waarvan je precies weet hoe je ermee om moet gaan (bijvoorbeeld FileNotFoundException of zo)
  • wanneer je ze daarna opnieuw verhoogt (bijvoorbeeld om de post-fail opruiming uit te voeren)
  • wanneer je de uitzondering naar een andere thread moet verplaatsen

Antwoord 5, autoriteit 6%

Het hangt af van wat je nodig hebt. Als u verschillende soorten uitzonderingen op verschillende manieren moet afhandelen, moet u meerdere catch-blokken gebruiken en zoveel mogelijk specifieke uitzonderingen opvangen.

Maar soms moet u alle uitzonderingen op dezelfde manier afhandelen. In dergelijke gevallen kan catch (uitzondering) in orde zijn. Bijvoorbeeld:

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

Antwoord 6, autoriteit 5%

Ik vind twee acceptabele toepassingen van catch(Exception):

  • Op het hoogste niveau van de applicatie (net voordat je terugkeert naar de gebruiker). Zo kun je een adequate boodschap geven.
  • Het gebruiken om uitzonderingen op een laag niveau te maskeren als zakelijke uitzonderingen.

Het eerste geval spreekt voor zich, maar laat me het tweede uitwerken:

Doen:

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

is het maskeren van bugs zoals @dimitarvp zei.

Maar het onderstaande is anders:

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

Op deze manier negeer je bugs niet en verberg je ze onder het tapijt. U geeft een uitzondering op hoog niveau met een meer verklarende boodschap aan hogere applicatielagen.

Het is ook altijd belangrijk om uitzonderingen op de juiste laag te beheren. Als u een uitzondering op een laag niveau escaleert naar een hoge bedrijfslaag, is het praktisch onmogelijk voor de hogere laag om deze goed te beheren.

In dat geval maskeer ik liever de uitzonderingen op laag niveau met een zakelijke uitzondering die een betere context en boodschap biedt en die ook de originele uitzondering heeft om op de details in te kunnen gaan.

Toch, als je meer concrete uitzonderingen kunt opvangen en ze beter kunt behandelen, moet je dat doen.

Als je in een codeblok een SQLExceptionen een NetworkExceptionkunt krijgen, moet je ze opvangen en voor elk van hen adequate berichten en behandeling geven.
Maar als je aan het einde van het try/catch-blok een Exceptionhebt die deze toewijst aan een BusinessException, dan vind ik dat oké.

In feite vind ik het voldoende wanneer hogere servicelagen alleen zakelijke uitzonderingen maken (met details erin).


Antwoord 7

Bovendien heeft @anthares al gereageerd:

Omdat wanneer je een uitzondering opmerkt je geacht wordt deze op de juiste manier af te handelen. En je kunt niet verwachten dat je allerlei uitzonderingen in je code kunt verwerken. Ook wanneer u alle uitzonderingen opvangt, kunt u een uitzondering krijgen die niet kan omgaan met en voorkomen dat code die zich bovenaan de stapel bevindt, deze correct afhandelt.

Het algemene principe is om het meest specifieke type te vangen dat je kunt.

catch(Exception)is een slechte gewoonte omdat het ook alle RuntimeException (niet-gecontroleerde uitzonderingen) vangt.


Antwoord 8

Dit kan Java-specifiek zijn:

Soms moet je methoden aanroepen die gecontroleerde uitzonderingen genereren. Als dit zich in je EJB / bedrijfslogica-laag bevindt, heb je 2 keuzes – vang ze of gooi ze opnieuw.

Het opvangen van specifieke uitzonderingsklassen betekent dat u uw acties waarvoor uitzonderingen kunnen worden gegenereerd, opnieuw moet analyseren als u kijkt hoe deze code met uitzonderingen omgaat. Je komt vaak in een “wat als…”-situatie terecht en het kan veel moeite kosten om erachter te komen of uitzonderingen correct worden afgehandeld.

Hergooien betekent dat code die uw EJB’s aanroept, bezaaid zal zijn met catchcode die normaal gesproken niets betekent voor de bellende klasse. nb het gooien van gecontroleerde uitzonderingen van EJB-methoden betekent dat u verantwoordelijk bent voor het handmatig terugdraaien van transacties.


Antwoord 9

Maar soms is het oké! Bijvoorbeeld als je een stukje code hebt dat iets ‘extra’s doet, waar je echt niet om geeft, en je wilt niet dat het je applicatie opblaast. Zo werkte ik onlangs aan een grote applicatie waarbij onze zakenpartners een bepaalde dagelijkse transactie wilden samenvatten in een nieuw logbestand. Ze legden uit dat het logboek niet zo belangrijk voor hen was en dat het niet als een vereiste kwalificeerde. Het was gewoon iets extra’s dat hen zou helpen de gegevens die worden verwerkt te begrijpen. Ze hadden het niet nodig, omdat ze de informatie elders konden krijgen. Dus dat is een zeldzaam geval waarin het prima is om uitzonderingen te vangen en te slikken.

Ik werkte ook bij een bedrijf waar alle Throwables werden gepakt en vervolgens werden teruggeworpen in een aangepaste RuntimeException. Ik zou deze aanpak niet aanraden, maar ik wil je er alleen op wijzen dat het klaar is.


Antwoord 10

Is het niet een ander geldig scenario om ervoor te zorgen dat een thread de uitzondering erin blijft vangen?

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

Other episodes