2011-01-25 16 views
60

Digamos que tenemos una estructura así:¿Los bloques Try/Catch anidados son una mala idea?

Try 
    ' Outer try code, that can fail with more generic conditions, 
    ' that I know less about and might not be able to handle 

    Try 
    ' Inner try code, that can fail with more specific conditions, 
    ' that I probably know more about, and are likely to handle appropriately 
    Catch innerEx as Exception 
    ' Handle the inner exception 
    End Try 

Catch outerEx as Exception 
    ' Handle outer exception 
End Try 

he visto algunas opiniones que anidan Try bloques como éste no es recomendable, pero no pude encontrar ninguna razón concreta.

¿Es este código incorrecto? Si es así, ¿por qué?

+2

No estoy seguro de qué tan exacto es el fragmento. Pero no hay un heckofalot que realmente conozcas cuando atrapes Exception. Puede ser cualquier cosa*. Considere aprovechar la cláusula When que VB.NET admite. –

Respuesta

63

Existen ciertas circunstancias en las que son una buena idea, p. un try/catch para todo el método y otro dentro de un bucle porque desea manejar la excepción y continuar procesando el resto de una colección.

Realmente, la única razón para hacerlo es si desea omitir el bit con errores y continuar, en lugar de desenrollar la pila y perder contexto. Abrir varios archivos en un editor es un buen ejemplo.

Dicho esto, las excepciones deberían ser solo eso: excepcionales. Un programa debe manejarlos, pero trate de evitarlos como parte del flujo de ejecución normal. Son computacionalmente costosos en lenguajes más (Python es una excepción notable).

Otra técnica que puede ser útil es la captura de tipos de excepciones específicas ...

Try 
    'Some code to read from a file 

Catch ex as IOException 
    'Handle file access issues (possibly silently depending on usage) 
Catch ex as Exception 
    ' Handle all other exceptions. 
    ' If you've got a handler further up, just omit this Catch and let the 
    ' exception propagate 
    Throw 
End Try 

Como ha señalado Gooch en los comentarios de abajo, también utilizamos try/capturas anidados en nuestras rutinas de tratamiento de errores .. .

Try 
     Try 
      'Log to database 
     Catch ex As Exception 
      'Do nothing 
     End Try 

     Try 
      'Log to file 
     Catch ex As Exception 
      'Do nothing 
     End Try 
    Catch ex As Exception 
     'Give up and go home 
    End Try 
+7

Iniciar sesión en un hilo de fondo es un lugar en el que usaré un try/catch interno. No quiero que el método termine porque no pudo documentar lo que estaba haciendo. – gooch

+0

@Gooch cierto, yo también hago eso, lo agregaré a mi respuesta. – Basic

31

en realidad no creo que haya nada inherentemente malo en anidados Try/Catch bloques, a excepción de que pueden ser difíciles de navegar y probablemente una señal de que se podía hacer algo de refactorización (el interior Try/Catch en su propio método, por ejemplo).

Pero sí quiero hacer frente a este comentario:

' Outer try code, that can fail with more generic conditions, 
' that I know less about and might not be able to handle 

Si usted no sabe cómo manejar excepciones en una situación particular, confía en mí: no lo hacen capturarlos. Es mejor dejar que la aplicación se bloquee (es decir, ya sabes, registrar, simplemente no tragarla) que atrapar algo de lo que no sabes cómo recuperarte y luego dejar que la aplicación continúe alegremente en su camino en una estado corrompido El comportamiento será impredecible a lo sumo desde ese momento.

+0

Eso es verdad. En el momento de atrapar la excepción externa, no me gustaría continuar. Estaba pensando en poder cerrar/reiniciar la aplicación correctamente y no sorprender al usuario con un "accidente" – Goro

+9

@Goro: en ese caso recomendaría un mecanismo de manejo de excepciones para toda la aplicación (por ejemplo, si esto es WinForms). , maneje el evento 'Application.UnhandledException') en lugar de los bloques' Try'/'Catch' por método. –

Cuestiones relacionadas