¿Cómo enseñar manejo de excepciones para nuevos programadores? [cerrado]

21

¿Cómo se hace para enseñar el manejo de excepciones a los programadores? Todas las demás cosas se enseñan fácilmente: estructuras de datos, ASP.NET, WinForms, WPF, WCF, lo que sea, todo se puede enseñar fácilmente.

Con Exception Handling, enseñarles try-catch-finally es solo la naturaleza sintáctica de Exception Handling.

Sin embargo, lo que debe enseñarse es: ¿qué parte de su código coloca en el bloque de prueba ? ¿Qué haces en el bloque de captura ?

Permítanme ilustrarlo con un ejemplo.

Está trabajando en un proyecto de formularios Windows Forms (una pequeña utilidad) y lo ha diseñado de la siguiente manera con 3 proyectos diferentes.

  1. UILayer
  2. BusinessLayer
  3. DataLayer

Si se produce una excepción (digamos que cargar un XDocument arroja una excepción) en DataLayer (el UILayer llama a BusinessLayer, que a su vez llama al DataLayer), ¿simplemente hace lo siguiente?

//In DataLayer
try {
    XDocument xd_XmlDocument = XDocument.Load("systems.xml");
} 
catch(Exception ex)
{
    throw ex;
}

que se arroja nuevamente en BusinessLayer y que se captura en UILayer donde lo escribo en el archivo de registro?

¿Es así como se maneja la gestión de excepciones?

Kanini
fuente
15
Si estabas va a hacer eso, usted no quiere catch (Exception ex) {ex tiro; } - en lugar de eso solo atrapa {throw; }
Steven Evers
44
No olvidemos finalmente los bloques?
Chris
1
Debe especificar el idioma en las etiquetas. Está entrando en más detalles de lo que es común en la mayoría de las implementaciones de excepciones e ignorando cosas fuera de los bloques. En C ++, por ejemplo, la parte más importante del manejo de excepciones es saber cómo escribir programas seguros para excepciones.
David Thornley
Espero que sepas que es una mala idea atrapar cualquier "Excepción". Debería haber anidado bloques catch para capturar excepciones específicas y manejarlas en consecuencia (no solo lanzar la excepción).
minusSeven

Respuestas:

29

Para explicar el manejo de excepciones, explique el concepto detrás de esto: el código donde ocurre un error con frecuencia no sabe cómo manejar ese error adecuadamente. El código que sabe cómo manejarlo correctamente podría ser la función que lo llamó, o podría estar más arriba en la pila de llamadas.

Cuando escribe una rutina que llama a una rutina que podría generar una excepción, si sabe cómo manejar ese error correctamente, coloque la llamada en un bloque try y coloque el código de manejo de errores en el bloque catch. Si no, déjelo solo y deje que algo sobre usted en la pila de llamadas maneje el error.

Decir "atrapar ex, tirar ex" no es una buena forma de manejar excepciones, ya que en realidad no maneja nada. Además, dependiendo de cómo funcione el modelo de excepción en su idioma, eso puede ser dañino si borra la información de seguimiento de la pila que podría haber utilizado para depurar el problema. Simplemente deje que la excepción se propague por la pila de llamadas hasta que llegue a una rutina que sepa cómo manejarla.

Mason Wheeler
fuente
44
1 para "... ya que en realidad no manejar cualquier cosa", nuevas personas a manejar tan a menudo piensan excepción medios de manipulación captura y no se dan cuenta si no se hace algo para reparar el problema, es que no manejo de excepciones, solo código hinchado.
Jimmy Hoffa
13

Como la mayoría de las cosas, las excepciones y el manejo de excepciones probablemente parecerán una solución en busca de un problema para los nuevos programadores hasta que demuestre por qué la solución aparentemente más simple (códigos de retorno de estilo C y errno) funciona tan mal. Comenzaría por motivar el problema y ponerlo en contexto. Muestra cómo se puede manejar el error usando códigos de retorno o variables globales / estáticas. Luego, dé ejemplos de por qué no funciona bien. Luego, y solo entonces, introduzca excepciones y explique que son una forma de señalización fuera de banda y que el punto principal es que el comportamiento predeterminado si ignora una excepción es pasar el dinero a la pila de llamadas a alguien que pueda manejarlo

En pocas palabras: mostrar cómo se realizó el manejo de errores en C hará que los estudiantes comprendan para qué son realmente las excepciones y por qué detectar excepciones que realmente no se pueden manejar es básicamente simular la forma en que se hicieron las cosas en la Edad Media.

dsimcha
fuente
2
¡+1 por la práctica docente de guiarlos en los códigos de retorno de estilo C tradicionales y números de error y mostrarles que funciona mal y, por lo tanto, enseñarles cómo funcionará es genial!
Kanini
3
@Kanini: En general, creo que la mayoría de las construcciones relativamente nuevas / de alto nivel parecen soluciones en busca de problemas y son fáciles de usar incorrectamente si no entiendes qué problema debían resolver y por qué se inventaron.
dsimcha
Estoy de acuerdo en que mostrar cómo se haría sin excepciones es bueno, pero luego viene la carga de explicar cuándo usar excepciones y cuándo usar otras técnicas (porque no todas las situaciones son excepcionales)
Matthieu M.
@ Matthieu: Correcto. Pero si comprende qué problemas históricos están destinados a resolver las excepciones, en lugar de aprender sobre ellos en el vacío, se vuelve más obvio que es tonto usarlos en situaciones no excepcionales.
dsimcha
bien, es por eso que obtuviste mi +1. Simplemente sentí que su respuesta podría interpretarse como "nunca use otro mecanismo" :)
Matthieu M.
5

Comenzaría con las Pautas de diseño para excepciones, que son cortas e incluyen DO, DO NOT y EVOID. También da las razones por qué.

En su caso de ejemplo, la sección revelvent sería Envolviendo excepciones

Y esperaría que se escribiera de esta manera. Tenga en cuenta que detecta una excepción específica e intenta agregar información para que se propague un mensaje más significativo. También tenga en cuenta que la excepción interna todavía se mantiene para fines de registro

//In DataLayer

try
{
XDocument xd_XmlDocument = XDocument.Load("systems.xml");
}
catch(FileNotFoundException ex)
{
        throw new TransactionFileMissingException(
                     "Cannot Access System Information",ex);
}

ACTUALIZACIÓN Kanini pregunta si es correcto tener este bloque de excepción en la capa de datos o si la comprobación del archivo está disponible para la capa empresarial.

Bueno, primero me gustaría señalar que la justificación de las excepciones de envoltura es esta

Considere envolver excepciones específicas lanzadas desde una capa inferior en una excepción más apropiada, si la excepción de la capa inferior no tiene sentido en el contexto de la operación de la capa superior.

Entonces, si cree que una capa superior debe saber sobre el archivo, su capa de datos debería verse así

//In DataLayer

XDocument xd_XmlDocument = XDocument.Load("systems.xml");

No intente sin captura.

Personalmente, creo que a menos que su capa de datos pueda hacer algo útil, como usar un sistema predeterminado.sml que es un recurso de ensamblaje, no hacer nada o envolver la excepción es una buena apuesta, ya que su registro le dirá qué método y qué archivo fue el problema. ( throw exen este caso o el preferido throwtambién, pero no agrega valor). Esto significa que una vez identificado, podrá solucionar el problema rápidamente.

Como ayuda, este ejemplo en particular también tiene el siguiente problema, ya que XDocument.Load puede arrojar cuatro excepciones.

  • ArgumentNullException
  • Excepcion de seguridad
  • FileNotFoundException
  • UriFormatException

No podemos garantizar con seguridad que el siguiente código no se lanzará y FileNotFoundException, simplemente porque podría estar allí cuando verificamos la existencia y desaparecer cuando cargamos. Tener eso disponible para la capa empresarial no ayudaría.

 if (File.Exists("systems.xml")) 
     XDocument.Load("systems.xml");

SecurityException es aún peor porque, entre otras razones, si esto se produce si otro proceso agarra tiene un bloqueo de archivo exclusivo, no obtendrá el error hasta que intente abrirlo para leerlo porque no hay un método File.CanIOpenThis (). Y si existiera tal método, todavía tiene el mismo problema que con File.Exists

Conrad Frix
fuente
Fijar: ¡Gracias! Pero, ¿es correcto tener este bloque de excepción en la capa de datos? ¿Debería comprobar si el archivo está disponible o no en la capa empresarial? De lo contrario, acepto su método para escribir el código.
Kanini
Solución: en mi idioma nativo, Kanini significa una computadora, mientras que Kani significa una fruta ;-)
Kanini
Puedo decir que no está demasiado molesto por mi error, pero lo siento mucho y lo he corregido.
Conrad Frix
1
Solución: ¿molesto? De ningún modo. En gran medida divertido. Mi hermano no ha dejado de reír desde que señalamos a él principalmente porque, no se parecen a una fruta de cualquier manera excepto quizás por la extraña forma de ...
Kanini
4

Hagamos un juego de roles. (esto no es una publicación de broma)

Debería hacer un taller donde representa la cadena de llamadas. Cada persona es un objeto. Necesitarás algunos novatos y algunas personas que entiendan que el "juego" ayuda.

Use un problema realmente simple como el archivo IO. gui-> model-> file_io

La persona que es el lector de archivos necesita decirle al siguiente ...

Primero hazlo con los códigos de retorno. (¿usa notas post-it?)

si las interacciones son "lo que dice el código" muy pronto, puede hacer que las personas se den cuenta de que las excepciones son excepcionales.

para códigos de retorno, pase una nota post-it.

para excepciones, levante las manos en el aire y diga cuál es el problema.

luego pídales que hagan "atrapar x, arrojar x" y ver que, mucho peor, el diagnóstico es lo que la GUI solo obtiene "el modelo tuvo una excepción".

Creo que esto funcionará para capacitar a las personas que tienes porque las personas entienden bastante bien las interacciones con otras personas.

Tim Williscroft
fuente
+1 para la idea del juego de roles. Nunca pensamos en eso antes. ¿Quién podría haber pensado que la enseñanza de la programación podría hacerse a través de Role Play?
Kanini
1

Me imagino que para entender las excepciones, primero debe comprender la relación niño / padre de las clases, por ejemplo. Si comprende que un niño puede heredar la funcionalidad de un padre, es posible que en un nivel primario entienda que si un niño tiene un problema que no puede resolver, pasará este problema (excepción) a su padre y dejará que el padre se ocupe con eso.

Esto se convierte en una relación encadenada hasta que terminas en un lugar donde algo sabe cómo manejar la excepción.

Y hasta donde finalmente llega, esta es la parte trivial ... cuando ocurre un problema, algo tiene que manejarlo para que el programa no salga fatalmente, después de que se maneja esa excepción, el bloque finalmente está allí, que siempre se ejecutará independientemente del intento de captura .

Un buen ejemplo de esto podría ser con las redes:

  • hacemos conexión
  • la conexión está bien, así que la usamos
  • cuando terminamos cerramos y liberamos recursos

o en caso de excepción:

  • hacer una conexión
  • se produce una excepción que algo maneja
  • en ese momento, liberamos conexión y recursos asociados
Chris
fuente
1

Entregue una Aplicación al novato que tenga muy buen manejo de Excepciones. Lanza alguna excepción en alguna parte y deja que la depuren con la ayuda de Logs. Al rastrear la propagación de la excepción, deberían poder depurarla. Haz este ejercicio 3 o 4 veces. Ahora simplemente elimine todo el manejo de Excepción del código y deje que intenten rastrear la misma excepción.

Creo que la apreciación por el código de manejo de excepciones será apreciada al instante.

Friki
fuente
Suena como un plan. ¿Tiene algún código de muestra disponible en Internet (digamos, sourceforge.net) que recomendaría?
Kanini
0

En mi opinión, debe pensar que el manejo de excepciones y las declaraciones de control de flujo son básicamente lo mismo. Los usa para controlar el flujo de sus programas según la condición en la que se encuentran actualmente. La diferencia es que el manejo de excepciones solo reaccionará cuando ocurra un error (o excepción).


fuente
@denny: Si bien estoy de acuerdo con que "el manejo de excepciones solo reaccionará cuando ocurra un error (o excepción)", no estoy seguro de la afirmación de que "el manejo de excepciones y las declaraciones de control de flujo son básicamente lo mismo". Respetuosamente no estoy de acuerdo allí. Es cierto que el bloque catch hace lo que debería hacer bajo esa condición. Sin embargo, el bloque de prueba no tiene nada que ver con el flujo o el control. El bloque finalmente, de nuevo, no tiene nada que ver con el flujo o el control. Tal vez, no entendí tu respuesta, pero ¿puedes aclarar para beneficio de mí y de otros?
Kanini
0

Probablemente no ayudaría a un nuevo programador, pero descubrí que entendía el concepto de excepciones mucho mejor una vez que comencé a usar mónadas en la programación funcional. Una mónada lo obliga a considerar cada "canal" a través del cual los datos pueden viajar dentro o fuera de un programa, ya que todo lo que hace proporciona una abstracción conveniente para "ocultar" parte de ese flujo de datos.

La idea de que una función puede tener diferentes tipos de salida, y una excepción es como un tipo de retorno de mayor prioridad de la función, es bastante clara.

Eso sí, entiendo que no es así como funcionan las excepciones en la mayoría de los idiomas (detalles de implementación), pero en un sentido abstracto, eso es lo que está sucediendo.

CodexArcanum
fuente
0

Finge que un mono está usando el teclado

Solía ​​decirles a mis muchachos cuando escriben código para fingir que un mono se sentará en el teclado y usará esta aplicación.

Esto les enseñó a anticipar todo tipo de cosas:

  • Datos perdidos
  • Archivos perdidos
  • Caracteres alfa cuando esperas números
  • División por cero

Creo que fue la palabra de tener un mono golpeando las llaves y haciendo lo que quisiera en lugar de seguirlo muy bien lo que hizo el truco. Funcionó para mi.

Michael Riley - también conocido como Gunny
fuente
Monos? Supongo que los usuarios de su empresa nunca escucharon eso ;-)
Kanini
@ Kanini - Buena. Eso fue en mis días en el Cuerpo de Marines. Solo quería que mis muchachos pensaran fuera de la caja cuando se trataba de atrapar errores. ¿Acabo de decir error trapping? Me refería al manejo de excepciones
Michael Riley - AKA Gunny