c# - ver - Si se le pide que corrija errores en un programa, encontrará más de 100 instancias de
variable debug c# (9)
Advertencia: este es un consejo general y las peculiaridades de su entorno pueden hacerlo imposible, por ejemplo, presiones de tiempo.
Suprimirlos a todos con la excepción de los puntos de entrada al sistema (métodos principales, puntos finales de servicio, pila de llamadas al principio del hilo, controladores de eventos, para el código de UI) y agregar el registro / manejo de errores a los lugares donde permanecen los controladores de excepciones .
Comenzar un proceso de agregar los controladores de nuevo en donde sea necesario, es decir, lugares donde las excepciones deben manejarse más abajo, con el registro adecuado o el informe de errores.
Hacer que el sistema vuelva a funcionar depende de tener un buen conjunto de pruebas de aceptación / regresión para verificar que el sistema sea correcto después de que se realicen todos los cambios.
catch(Exception ex)
{
}
¿Cuál es la mejor manera de proceder?
Ripear a todos y dejar que se estrelle? Añadir código de registro? Cuadros de mensaje? Esto está en C #.
Arregle los errores que estaba dispuesto a hacer e informe los bloques de tragar de excepciones como errores nuevos y críticos.
Cambie los bloques de captura de la siguiente manera:
catch (Exception ex)
{
Logger.Log(String.Format(
System.Globalization.CultureInfo.InvariantCulture,
"An exception is being eaten and not handled. "+
"This may be hiding critical errors./n"+
"Exception: {0}",
ex));
}
Depende en parte de lo agresivo que puedas ser. ¿Es esta aplicación interna o externa? ¿Sus cambios se implementarán en sistemas en vivo pronto? ¿Tiene errores específicos que corregir, o solo se considera un desastre?
Para reducir el número de errores lo más rápido posible, pero con el mayor riesgo de daños graves, simplemente elimine todos los bloques de captura y deje que aumenten las excepciones. Para un enfoque mucho más delicado, simplemente agregue el registro para comenzar.
También debe hablar con quienquiera que haya escrito la aplicación para comenzar, si es posible. Trate de averiguar por qué tienen tantos bloques para tragar excepciones. ¿Entienden realmente las excepciones? Una cierta cantidad de tacto es necesario aquí, sospecho :)
Siguiente parada: pruebas unitarias ...
El primer objetivo intermedio es obtener una buena imagen de qué excepciones se están ignorando y dónde; para ese propósito, simplemente puede agregar el código de registro a cada uno de esos horribles bloqueos de catch
, mostrando exactamente qué bloque es, y qué captura y ocultando. Ejecute el conjunto de pruebas sobre el código así instrumentado, y tendrá un "plano" inicial para el trabajo de reparación.
Si no tiene un conjunto de pruebas, primero, haga que las pruebas de una unidad puedan esperar (consulte el excelente libro de Feathers sobre cómo trabajar con código heredado: el código heredado es su problema aquí ;-), pero necesita un conjunto de pruebas de integración que se puedan ejecutar automáticamente y haga cosquillas a todos los errores que se supone que debe solucionar.
A medida que vaya y corrija error tras error (muchos de ellos no serán causados por los bloques de captura excesivamente amplios, simplemente ocultos / "pospuestos" por ellos ;-), asegúrese de trabajar de forma principalmente "basada en pruebas": agregue un prueba de unidad que corrige el error, confirma que se rompe, corrige el error, vuelve a ejecutar la prueba de unidad para confirmar que el error se ha ido. Su conjunto de pruebas de unidades en crecimiento (con todo lo posible burlado o falso) se ejecutará rápidamente y podrá seguir ejecutando a bajo costo mientras trabaja, para capturar posibles regresiones lo antes posible, cuando aún son fáciles de arreglar.
El tipo de tarea que se le asignó es en realidad más difícil (y, a menudo, más importante) que las tareas de desarrollo de software de "alto prestigio", como prototipos y nuevas arquitecturas, pero a menudo es mal interpretado y subestimado (¡y por lo tanto no es recompensado!) /clientela; asegúrese de mantener un canal de comunicación muy claro y abierto con los interesados, señalando la enorme cantidad de trabajo exitoso que está realizando, lo desafiante que es y (por su propio bien más que el suyo propio), cuánto tendrían salvados haciéndolo bien en primer lugar (tal vez la próxima vez que lo hagan ... Lo sé, soy un optimista de ojos salvajes por naturaleza ;-). Tal vez incluso le asignen un socio en la tarea, y luego puede hacer revisiones de código y programación de pares, aumentando enormemente la productividad.
Y, por último pero no menos importante, ¡ buena suerte! - desafortunadamente, lo necesitarás ... afortunadamente, como dijo Jefferson, "cuanto más trabajo, más suerte parece tener" ;-)
Guau....
Dudaría en robarlos porque las probabilidades son que solo crearía más "bugs". Un primer paso sería agregar el registro para que sepa qué está pasando. Una vez que tenga suficiente información, podrá proceder a la refactorización ... con cuidado
Las pruebas unitarias serían una excelente manera de probar cualquier refactorización que haga. También sugeriría tener un montón de ellos en su lugar.
La solución que debe elegir depende en gran medida del entorno en el que esté trabajando.
Las pautas de codificación que he escrito y presentado a la mayoría de mis clientes, establecen explícitamente que las cláusulas de captura vacías sin comentarios (exactamente como lo ha mostrado en su pregunta) pueden eliminarse sin discusión alguna. La razón por la que escribí esta regla es porque encuentro este tipo de declaraciones todo el tiempo y casi siempre esconden muchos errores. Por lo general, cuanto más código hay en el bloque try, más errores ocultan. A lo largo de los años, he descubierto (y resuelto) muchos errores simplemente eliminando las cláusulas vacías. El procedimiento suele ser el mismo:
- Quito un retén.
- El código va a producción.
- Después de un tiempo, los clientes se quejaron de que el programa dejó de funcionar (obtuvo una excepción).
- Empiezo a investigar el problema y descubro que esta parte del sistema nunca funcionó realmente, y varios desarrolladores han intentado encontrar errores relacionados con esta causa, pero nunca encontraron el problema. O peor aún, encontraron el problema y escribieron esa declaración de captura para "resolver" el problema.
- Arreglo el problema real que se barrió debajo de la alfombra y cierro varios informes de errores a la vez.
Si bien este método me ha servido bien a mí (ya mis clientes) en estos años, hay un ''pero''. Por ejemplo, uno de mis clientes actuales es una institución médica y los desarrolladores estaban interesados en usar mis pautas de codificación. Sin embargo, insistí en que eliminarían esa regla particular de las pautas. Mientras que su software tiene una gran cantidad de esas declaraciones de captura vacía (más de 100) y esas cosas molestas ocultan muchos errores y me atacan todo el tiempo mientras trabajo con su software; Debes tener mucho cuidado en este tipo de aplicaciones. En este escenario, comenzaría por agregar sentencias de registro, en lugar de eliminarlas. Después de esto, puede eliminarlos lentamente uno por uno cuando sepa qué tipo de excepciones ocurren y por qué el desarrollador anterior agregó esa declaración catch en primer lugar.
En todos los casos, debe tener una declaración general de capturas en la parte superior de su aplicación (o tener un controlador de excepciones en su aplicación web) que registrará cualquier excepción que surja.
Nota adicional, mis pautas también tienen en cuenta que configuraría Visual Studio para interrumpir todas las excepciones, yendo a Debug / Exceptions ... / Common Language Runtime Exceptions y marque la casilla de verificación "Lanzar". De esta manera usted detecta una excepción de inmediato.
Obviamente, el registro de todas las excepciones suprimidas es el primer lugar para comenzar: la supresión general es útil de vez en cuando cuando necesita asegurarse de que su código se degrada con gracia en todas las circunstancias (es decir, donde no desea que lo atrape un tipo de excepción que no pudo anticipar), pero puede ocultar un problema no anticipado que requiere más manejo que simplemente ser ignorado, por lo que es imperativo que todos los controladores de excepciones informen, como mínimo, que se ha eliminado una excepción, por lo que tiene un rastro claro de pistas para seguir si surge un comportamiento inesperado.
La eliminación de las capturas es una tontería, ya que habrá muchos casos en los que es necesario "manejar" algunas excepciones para que el programa funcione correctamente (aunque puede estar en desacuerdo con la forma en que se manejan y puede haber riesgos asociados con este enfoque, el original). el autor tuvo una razón para escribir el código de esta manera. Ig no ha agregado un comentario que explique su razón, entonces no asuma que usted sabe mejor que él, especialmente no en una forma de "búsqueda y reemplazo global").
Sin embargo, parece que nadie ha señalado el punto de inicio más obvio y más rápido de implementar: vaya a "Depurar -> Excepciones" y habilite "Ruptura cuando se produce una excepción" para la sección "Excepciones de Common Language Runtime Exceptions". Esto hará que el depurador se rompa por cada excepción que se lance (antes de que se llame al bloque catch del programa para manejarlo), por lo que podrá probar la aplicación bajo el depurador y determinar qué bloques catch están eliminando qué excepciones cuando intenta para repetir un error determinado, desde el cual puede emitir un juicio sobre si ese bloqueo de captura en particular tiene alguna influencia sobre el error en cuestión.
Un enfoque que podría tomar para obtener una imagen de lo que está sucediendo sería tomar cada uno de los bloques de Exception
vacíos y hacer que cada uno llame al método breakOnException(Exception e)
.
Este método no tiene que hacer nada excepto (digamos) registrarlo. Luego, puede ejecutar el programa bajo un depurador con un punto de interrupción en este método y ver si se alcanza el punto de interrupción, y luego investigar las causas. Desafortunadamente eso es un poco laborioso.
¿Tiene pruebas unitarias que se pueden ejecutar contra el código en el depurador? Tendría sentido hacer lo anterior con estos.