Cómo implementar el manejo de errores [cerrado]

13

Aunque he programado a nivel profesional durante algunos años, todavía no entiendo completamente el manejo de errores. Aunque mis aplicaciones funcionan bien, el manejo de errores no se implementa a nivel profesional y es una combinación de varias técnicas.

No hay una estructura detrás de mi manejo de errores. Me gustaría aprender y comprender cómo se implementa a nivel profesional. Esta es un área donde me falta conocimiento.

¿Cuándo debo usar una excepción y cuándo debo devolver un estado de éxito para que se verifique en el flujo lógico? ¿Está bien mezclar excepción y devolver un estado?

Codifico en C # principalmente.

James Jeffery
fuente
2
¿Por qué bajar el voto? Estoy haciendo una pregunta seria sobre la implementación del manejo de errores y cómo se hace. Si este no es el mejor lugar para hacer esa pregunta entre los programadores, ¿dónde está? Realmente me molesta cuando la gente rechaza esas preguntas porque no hay otro lugar para hacer esa pregunta. Es posiblemente el único lugar en la web donde voy a obtener una respuesta confiable y posibles recursos. Entonces, en lugar de rechazar una pregunta que otras personas seguramente buscarán en Google, ¿no sería más fácil responderla?
James Jeffery
66
Tu pregunta es muy amplia. Tal vez podría reducir el alcance al relacionar ejemplos específicos de cómo no logró sus objetivos de codificación.
Andyz Smith
Hay muchos artículos en la web sobre el manejo de errores: Pruebe esto: msdn.microsoft.com/en-us/library/seyhszts.aspx
Nir Kornfeld

Respuestas:

25
  1. Use excepciones para cosas excepcionales, cosas que razonablemente no puede esperar encontrar con demasiada frecuencia, cosas que indican que algo sale mal. Por ejemplo, si la red está inactiva, es algo excepcional para un servidor web. Si la base de datos no está disponible, significa que algo está mal. Si falta el archivo de configuración, probablemente significa que el usuario lo echó a perder.

  2. No use excepciones para manejar código incorrecto. Para verificar la exactitud del código, debe usar las aserciones o, en .NET Framework 4 y posteriores, los contratos de código (que reemplazan las aserciones y tienen características adicionales, particularmente valiosas).

  3. No use excepciones en casos no excepcionales. El hecho de que el usuario, cuando se le pide que ingrese un número, ingresó "perro" no es tan excepcional como para merecer una excepción.

  4. Tenga cuidado al elegir los tipos de excepciones. Crea tus propios tipos cuando sea necesario. Elija cuidadosamente la herencia, teniendo en cuenta que la captura de los padres también atrapará a los hijos. Nunca throw Exception.

  5. No use códigos de retorno para errores. Los códigos de error son fácilmente enmascarados, ignorados, olvidados. Si hay un error, puede manejarlo o propagarlo a la pila superior.

  6. En los casos en que se espera que un método devuelva un error y el error no sea excepcional, use enumeraciones, nunca números de error. Ejemplo:

    // Note that the operation fails pretty often, since it deals with the servers which are
    // frequently unavailable, and the ones which send garbage instead of the actual data.
    private LoadOperationResult LoadProductsFromWeb()
    {
        ...
    }

    El significado de LoadOperationResult.ServerUnavailable, LoadOperationResult.ParsingErroretc. es mucho más explícito que, digamos, recordar que el código 12 significa que el servidor está inactivo y el código 13, que los datos no se pueden analizar.

  7. Use códigos de error cuando se refieren a los comunes, conocidos por todos los desarrolladores que trabajan en el dominio específico. Por ejemplo, no reinvente un valor de enumeración para HTTP 404 Not Found o HTTP 500 Internal Server Error.

  8. Cuidado con los booleanos. Tarde o temprano, querrá saber no solo si un método específico tuvo éxito o no, sino por qué. Las excepciones y enumeraciones son mucho más poderosas para eso.

  9. No atrape todas las excepciones (a menos que esté en la parte superior de la pila). Si detecta una excepción, debe estar listo para manejarla. Capturar todo muestra que no te importa si tu código se ejecuta correctamente. Esto puede resolver el "No quiero buscar en este momento cómo solucionar esto", pero tarde o temprano le hará daño.

  10. En C #, nunca vuelva a lanzar excepciones como esta:

    catch (SomeException ex)
    {
        ...
        throw ex;
    }

    porque estás rompiendo la pila Haz esto en su lugar:

    catch (SomeException)
    {
        ...
        throw;
    }
  11. Haga un esfuerzo al escribir mensajes de excepción. Cuantas veces he visto algo como throw Exception("wrong data")o throw Exception("shouldn't call this method in this context"). Otros desarrolladores, incluido usted mismo seis meses después, no tendrían idea de qué datos están mal y por qué o por qué no deberíamos llamar a algún método en un contexto, ni a qué contexto precisamente.

  12. No mostrar mensajes de excepción al usuario. No se esperan para la gente común y, a menudo, incluso son ilegibles para los propios desarrolladores.

  13. No localice mensajes de excepción. Buscar en la documentación un mensaje localizado es agotador e inútil: cada mensaje debe estar en inglés y solo en inglés.

  14. No se centre exclusivamente en excepciones y errores: los registros también son extremadamente importantes.

  15. En .NET, no olvide incluir excepciones en la documentación XML del método:

    /// <exception cref="MyException">Description of the exception</exception>

    La inclusión de excepciones en la documentación XML facilita mucho las cosas para la persona que usa la biblioteca. No hay nada más molesto que tratar de adivinar qué excepción podría ser lanzada por un método y por qué.

    En este sentido¹, el manejo de excepciones de Java proporciona un enfoque más estricto y mejor. Te obliga a lidiar con las excepciones potencialmente lanzadas por los métodos llamados, o declarar en tu propio método que puede arrojar las excepciones que no manejas, haciendo las cosas particularmente transparentes.


¹ Dicho esto, la distinción de Java entre excepciones y errores es bastante inútil y confusa, dado que el lenguaje ha marcado y desmarcado las excepciones. Afortunadamente, .NET Framework solo tiene excepciones y no tiene errores.

MainMa
fuente
Aprendí un poco de esto, ¿puedo preguntar de dónde vino la lista? Sitio o experiencia personal? De cualquier manera trabajo excepcional (¿jeje lo entiendes?).
Shelby115
@ Shelby115: la lista proviene, en orden: Stack Exchange, experiencia personal y Code Complete de Steve Mcconnell.
Arseni Mourzenko
¡Gracias @MainMa que es una excelente respuesta! Solía ​​tener Code Complete cuando estaba en la universidad, pero alguien lo robó. No pude leerlo.
James Jeffery
@JamesJeffery: luego pida prestada la segunda edición en una biblioteca, o compre una: es uno de los raros libros relacionados con el desarrollo que vale totalmente la pena.
Arseni Mourzenko
@MainMa Recién ordenado de Amazon, gracias: DI también posee Clean Code, y me olvidé por completo del Capítulo 7.
James Jeffery
1

Creo que la lista de MainMa es muy completa. Solo agregaré algunos de los míos:

  1. Lea el artículo de Eric Lippert sobre cómo clasifica las excepciones. Particularmente importante es su punto de no detectar excepciones que en realidad son errores en su código. ¡Arregla el código en su lugar!
  2. Si sabe que puede ocurrir una excepción Y puede hacer algo al respecto, manejarlo, pero limite el alcance de su intento de captura y captura la excepción específica que espera. Es decir, no hagas esto:

public void Foo() {
    try {
        //get input from use
        //do calculations
        //open file
    }
    catch (Exception ex) {
       //handle exception
    }
}

En cambio, haz esto:

public void Foo() {
    //get input from use
    //do calculations
    try {
        //open file
    }
    catch (FileOpenException ex) {
       //handle exception
    }
}
  • No use excepciones para el flujo de control. Por ejemplo, no arroje una ClientNotFoundException en un diálogo de búsqueda (un cliente no encontrado no es excepcional en esta situación) y espere que el código de llamada muestre un mensaje "No se encontraron resultados" cuando esto sucede.

  • ¡No te tragues las excepciones!

  • Tenga en cuenta que manejar realmente una excepción solo puede significar 3 cosas:

    1. Vuelva a intentar la operación. Solo válido si el problema es transitorio.
    2. Prueba una alternativa.
    3. Notificar a alguien sobre el problema. Solo es válido si la notificación es procesable, lo que significa que el usuario puede hacer algo al respecto.

    Si ninguna de estas opciones se aplica, entonces probablemente no debería detectar esa excepción. Sin embargo, debe registrarlo y luego cancelar la operación o cerrar. Por supuesto, esto depende de cuáles sean sus requisitos con respecto a la corrección frente a la robustez.

Miguel
fuente