¿Por qué debería escribir todas las declaraciones dentro de Try-Catch?

12

El jefe de mi compañía dice que debo escribir todo, es decir TODO mi código dentro de las declaraciones Try-catch. Ahora, puedo entender el enfoque de `` más vale prevenir que curar '' aquí, pero ¿no es demasiado descabellado pensar que habrá una excepción cuando se creen las Etiquetas, la posición del formulario está establecida? Ha habido casos en los que las excepciones en operaciones tan simples.

Chipre
fuente
44
Esto suena como términos de moda por las mismas personas que dicen que todo SQL debe escribirse como procedimientos almacenados para un mejor rendimiento.
Spong
55
¿Preferiría que "si su código crea un error de tiempo de ejecución, lo despiden"? El juego del pollo es divertido hasta que veas a tu oponente tirar el volante y el pedal del freno por la ventana.
JeffO
44
@Jeff O - Realmente creo que en el desarrollo de software el oponente es un tren de carga.
Joris Timmermans el
55
La mejor expresión que he escuchado para este estilo de manejo de excepciones es "Clavar el cadáver en posición vertical", lo que significa que deja la aplicación en un estado inesperado. Fail Fast, Fail Loudly es un enfoque mucho más moderno, por lo que puede solucionar todos los errores.
Brook
2
El tema de la solicitud es irrelevante ... solo decir "el jefe de mi compañía dice que debo codificar ..." es una gran bandera roja. Es microgestión ... este no es su trabajo.
JoelFan

Respuestas:

14

El jefe de mi compañía dice que debo escribir todo, es decir TODO mi código dentro de las declaraciones Try-catch.

Bueno, esto es un poco exagerado y solo conduce a un código ruidoso. ¿Cuáles son los beneficios de tener todo el código (cada método, por ejemplo) escrito con un controlador try catch? Simplemente le dice que hay un error que se debe corregir en la mayoría de los casos. Muchas veces, la excepción puede y debe evitarse en primer lugar.

Una mirada en el seguimiento de la pila es mayormente suficiente para revelar la causa en su código, incluso si el método de falla no realiza la captura en sí. Hay ocasiones en que los desarrolladores corrompen los rastros de la pila en excepciones, pero ese es mucho más a menudo el caso cuando tienes muchos manejadores de excepciones. Como cualquier cosa: un poco es bueno, pero demasiado es veneno.

El manejo de excepciones es bastante simple:

Capturar excepciones

  • siempre que necesite una acción especial como reacción a la excepción
  • cada vez que una excepción dejaría el programa en un estado inconsistente si no se maneja

Si lo piensas bien, siempre hay un solo lugar que es bueno para manejar una excepción que ocurre. Y así, el controlador debe estar en ese lugar.

En primer lugar, ni siquiera se deben lanzar muchas excepciones, así que no construya sus estructuras de control en torno al manejo de excepciones, más bien trate de evitar la posible aparición de excepciones siempre que sea posible.

Recuerde chocar temprano cuando las cosas van (irreparablemente) mal. Poner todo el código en las declaraciones try-catch es absurdo, pero no olvide informar y registrar TODAS las excepciones.

Halcón
fuente
+1 No solo conduce a un código ruidoso, sino a un rendimiento aún peor. Cuando coloca declaraciones en un bloque de prueba, el compilador HotSpot no podrá aplicar optimizaciones que de otro modo haría.
Oliver Weiler
@Oliver Weiler: ¿Tiene una cita que explique qué optimizaciones no realiza el compilador HotSpot en los bloques try / catch?
Kaypro II
16

pero no es demasiado descabellado pensar que habrá una excepción cuando se creen las Etiquetas, se establece la posición del formulario. Ha habido casos en los que las excepciones en operaciones tan simples.

¡Absolutamente sí! Siempre hay una manera de que las cosas salgan mal que no previste. Y "corazón de pollo" es una expresión ridícula para usar en este contexto; El desarrollo de software no se trata de demostrar su machismo ignorando posibles problemas.

Lo que es una pregunta válida es si es útil que las excepciones se capturen en el punto donde sus estándares de codificación dicen que tienen que hacerlo. Su declaración dice que debe tener un bloque try / catch alrededor de cada cuerpo de método, y eso es realmente absurdo porque a menudo no puede hacer algo útil de inmediato con una excepción, y ese es realmente el punto de excepciones: que puede elegir dejarlos propagar la pila de llamadas a tratar en el punto apropiado.

Michael Borgwardt
fuente
13
Mis aplicaciones saben mejor que lanzar excepciones o recibirán la paliza de sus vidas. Una vez que piensan que tienes un corazón de pollo, se estrellarán sobre ti.
JeffO
@Michael Borgwardt: jeje, así que me rechazaste. Usted votó negativamente sobre esta pregunta y el único voto negativo está en mi publicación. Parece que tienes un problema grave con tu ego o tu autoestima. Me di cuenta de eso en otras preguntas también. Ya sabes, otros programadores también tienen buenas respuestas.
Falcon el
@ Falcon: no voté en contra de nada sobre esta pregunta. No tengo idea de lo que te lleva a creer lo contrario, pero si alguien tiene un problema grave de ego, eres tú.
Michael Borgwardt
@Michael Borwardt: Quizás estoy equivocado. En ese caso me disculpo. Podría ser que ese sea el voto negativo en su propia pregunta que me hizo pensar que usted votó negativamente aquí. Lo siento.
Falcon
8

Yo cambiaría esto al revés. Sí, como regla general, el manejo de excepciones es algo bueno, pero ¿ puede manejar cada excepción posible de manera sensata en el punto en que se detecta? A veces, particularmente si no está escribiendo software de misión crítica, es mejor simplemente bloquearse y quemarse de una manera controlada a mitad de camino cuando las cosas van terriblemente mal.

Si no puede estar 100% seguro de que puede manejar cada una de las excepciones que posiblemente puedan detectarse, probablemente sea mejor escribir algún tipo de controlador de excepciones general, envolviendo el ciclo principal del programa, la mecánica exacta de cómo hacerlo obviamente depende del idioma en el que esté trabajando. Allí, registre tantos detalles sobre la excepción como pueda, guarde el estado del programa (en otro lugar que no sea el almacén de datos con el que el usuario está trabajando actualmente; recuerde, todo puede estar dañado en este punto ), y así. Luego, vuelva a lanzar la excepción y deje que el SO la maneje como lo considere conveniente. En este controlador de excepciones general, prepárate para una falla catastrófica. Luego, cuando se reinicie el programa, observe si este estado es de alguna manera útil y restaure lo que se puede recuperar si lo es; y posiblemente ofrezca al usuario que le envíe un informe de error.

un CVn
fuente
55
+1: Nunca atrape una excepción si no puede tratarla de inmediato correctamente. (Por desgracia, a veces tienes que atraparlo solo para dejarlo libre de nuevo pero etiquetado como un tipo diferente, como parte de la coacción API: lo odio).
Donal Fellows
6

En general, el uso de try / catch está en desuso, porque el bloque catch es muy costoso desde el punto de vista de los recursos. El uso de Try / catch me recuerda la gestión de riesgos . La gestión de riesgos tiene dos dimensiones:

  1. La probabilidad de que ocurra el riesgo
  2. El daño que puede tener

Ahora, si sales de tu casa, es muy poco probable que un piano caiga sobre tu cabeza en algún lugar (tal vez 0.001%), pero puede matarte.

El manejo de excepciones es así. Intentar bloquear no es caro. Pero catch block es realmente costoso, ya que necesita crear una tabla de seguimiento de pila y hacer otras cosas. Por lo tanto, al tomar una decisión sobre los bloques try / catch, debe considerar cuántas veces probablemente golpee el bloque catch. Si entre 10,000 usos, solo lo golpeas 1 vez, entonces úsalo. Pero si se trata de un formulario, y el usuario probablemente no lo llena correctamente un 50% de las veces, entonces debe evitar poner un bloque try / catch en acción allí.

En lugares donde la probabilidad de ocurrencia de excepción es alta, se recomienda usar if {} else {}bloques para evitar la ocurrencia de excepción. Por ejemplo, donde desea dividir dos números, en lugar de escribir:

try
{
    int result = a/b;
}
catch (DivisionByZeroException ex)
{
    // Showing a message here, and logging of course.
}

Deberías escribir:

if (b == 0)
{
    int result = a/b;
}
else
{
    // Showing a message to user to change the value of b, etc.
}
Saeed Neamati
fuente
2
+1 por usar if / else para lidiar con "excepciones" que son básicamente solo lógica de aplicación.
Morgan Herlocker
Si está relacionado con el usuario, recuerde que las computadoras son masivamente más rápidas que las personas. Es probable que solo se produzca una excepción en el 50% de los envíos de formularios unas pocas veces por segundo, incluso con muchos usuarios.
Donal Fellows
1
No estoy de acuerdo con usted para evitar los bloques try / catch. Intentar constantemente anticipar excepciones es propenso a errores, es costoso para el desarrollador y hace que su código sea más difícil de leer. Un bucle que arroja un millón de excepciones y las atrapa tarda 500 ms en ejecutarse en mi máquina (frente a 1 ms para un bucle vacío), lo que no es una diferencia de rendimiento en el mundo real en el 99,99% de los casos (y todo el código de la interfaz de usuario). Debe usar excepciones, excepto en los casos en que sepa que la penalización de rendimiento es importante, ya que hacen que su código sea más confiable y le permiten asumir que el código anterior se ejecutó con éxito.
Kaypro II
@ cosmic.osmo, ¿recuperas el stacktrace o simplemente lo atrapas?
3

Deberías usar try-catch cuando sea apropiado, pero por favor, oh, no captures todas las excepciones y ni siquiera lo registres. En ese punto, es olor a código y trabajo de mala calidad.

ist_lion
fuente
1
+1 para iniciar sesión. Los programas en la naturaleza son cajas negras. Cuando fallan, un registro que dice "Esto es lo que sucedió" ayuda mucho a resolver el problema. He tenido errores en mis programas que no se informaron, y se descubrieron solo después de que los encontré en el registro.
Andrew Neely
2

Personalmente no soporto las excepciones, son MUY, MUY, MUY difíciles de manejar correctamente. ¡Y tratar de corregir los datos corruptos es MUY, MUY, MUY difícil!

http://blogs.msdn.com/b/mgrier/archive/2004/02/18/75324.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2004/04/22/118161.aspx

http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx

http://www.joelonsoftware.com/items/2003/10/13.html

Si no llama a todas las funciones como:

try
{
    TrivialFunction();
}
catch(TypeAException)
{
    //MaybeFix
}
catch(TypeBException)
{
    //MaybeFix
}
catch(TypeCException)
{
    //NO FIX - CORRUPT DATA
}
catch(TypeDException)
{
    //NO FIX - UNKNOWN STATE
}
catch(OutOfMemoryException)
{
    //Try to fix this one! Destructors might allocate on their own ;)
}
catch(Exception)
{
    //Nothing to see here, move on, everything is OK ;)
}

No hay forma de que limpie correctamente en cada punto de salida. ¡Las excepciones son DURAS!

Lo único bueno de las excepciones es que si no las detecta, la aplicación se bloquea por un comportamiento inesperado.

Descifrador
fuente