usuario try todas tipos que programacion por más las existen excepciones específicos errores definidas comunes como catch capturar c# logging exception-handling

c# - try - ¿Debo detectar excepciones solo para registrarlas?



todas las excepciones en c# (15)

A menos que vaya a cambiar la excepción, solo debe iniciar sesión en el nivel donde va a manejar el error y no volver a lanzarlo. De lo contrario, su registro solo tiene un montón de "ruido", 3 o más del mismo mensaje registrado, una vez en cada capa.

Mi mejor práctica es:

  1. Solo intente / capture en métodos públicos (en general, obviamente, si atrapa un error específico, lo buscará allí)
  2. Solo inicie sesión en la capa de la interfaz de usuario justo antes de suprimir el error y redirigir a una página / formulario de error.

¿Debo atrapar excepciones para fines de registro?

public foo(..) { try { ... } catch (Exception ex) { Logger.Error(ex); throw; } }

Si tengo esto en su lugar en cada una de mis capas (DataAccess, Business y WebService) significa que la excepción se registra varias veces.

¿Tiene sentido hacerlo si mis capas están en proyectos separados y solo las interfaces públicas tienen try / catch en ellas? ¿Por qué? Por qué no? ¿Hay un enfoque diferente que pueda usar?


Definitivamente no. Debería encontrar el lugar correcto para manejar la excepción (en realidad, hacer algo, como catch-and-not-rethrow), y luego registrarla. Por supuesto, puede y debe incluir la traza completa de la pila, pero seguir su sugerencia arrojaría el código con bloques try-catch.


Depende de la Excepción: si esto realmente no sucediera, definitivamente lo registraría. Por otro lado: si espera esta Excepción, debe pensar en el diseño de la aplicación.

De cualquier forma: al menos debe tratar de especificar la excepción que desea volver a generar, capturar o registrar.

public foo(..) { try { ... } catch (NullReferenceException ex) { DoSmth(e); } catch (ArgumentExcetion ex) { DoSmth(e); } catch (Exception ex) { DoSmth(e); } }


Es posible que desee buscar estilos de manejo de excepciones estándar, pero mi entendimiento es el siguiente: manejar excepciones en el nivel donde puede agregar detalles adicionales a la excepción, o en el nivel donde presentará la excepción al usuario.

en su ejemplo, no está haciendo otra cosa que atrapar la excepción, iniciar sesión y lanzarla de nuevo ... ¿por qué no simplemente atraparla en el nivel más alto con un intento / captura en lugar de dentro de cada método si todo lo que hace es iniciar sesión?

solo lo manejaría en ese nivel si fuera a agregar información útil a la excepción antes de volver a lanzarla: ajuste la excepción en una nueva excepción que cree que tenga información útil más allá del texto de excepción de bajo nivel que normalmente significa poco para cualquier persona sin algún contexto ...


Es posible que desee iniciar sesión en el nivel más alto, que generalmente es su UI o código de servicio web. Iniciar sesión varias veces es una especie de desperdicio. Además, desea conocer toda la historia cuando mira el registro.

En una de nuestras aplicaciones, todas nuestras páginas se derivan de un objeto BasePage, y este objeto maneja el manejo de excepciones y el registro de errores.


Es una buena práctica traducir las excepciones . No solo inicie sesión. Si desea conocer el motivo específico por el que se lanzó una excepción, presente excepciones específicas:

public void connect() throws ConnectionException { try { File conf = new File("blabla"); ... } catch (FileNotFoundException ex) { LOGGER.error("log message", ex); throw new ConnectionException("The configuration file was not found", ex); } }


La regla general es que solo atrapa una excepción si realmente puede hacer algo al respecto. Entonces, en la capa de Negocio o Datos, solo detectaría la excepción en una situación como esta:

try { this.Persist(trans); } catch(Exception ex) { trans.Rollback(); throw ex; }

Mi Business / Data Layer intenta guardar los datos; si se genera una excepción, cualquier transacción se retrotrae y la excepción se envía a la capa de la interfaz de usuario.

En la capa UI, puede implementar un controlador de excepción común:

Application.ThreadException + = new ThreadExceptionEventHandler (Application_ThreadException);

Que luego maneja todas las excepciones. Podría registrar la excepción y luego mostrar una respuesta amigable para el usuario:

static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) { LogException(e.Exception); } static void LogException(Exception ex) { YYYExceptionHandling.HandleException(ex, YYYExceptionHandling.ExceptionPolicyType.YYY_Policy, YYYExceptionHandling.ExceptionPriority.Medium, "An error has occurred, please contact Administrator"); }

En el código de UI real, puede capturar excepciones individuales si va a hacer algo diferente, como mostrar un mensaje amistoso diferente o modificar la pantalla, etc.

Además, solo como recordatorio, siempre trate de manejar los errores, por ejemplo dividir entre 0, en lugar de lanzar una excepción.


Mi método es registrar las excepciones solo en el controlador. El manejador ''real'' por así decirlo. De lo contrario, el registro será muy difícil de leer y el código menos estructurado.


Necesita desarrollar una estrategia para manejar excepciones. No recomiendo la captura y el nuevo lanzamiento. Además de las entradas de registro superfluas, hace que el código sea más difícil de leer. Considere escribir en el registro en el constructor para la excepción. Esto reserva el try / catch para las excepciones de las que desea recuperar; haciendo que el código sea más fácil de leer Para tratar con excepciones inesperadas o irrecuperables, es posible que desee intentar / capturar cerca de la capa más externa del programa para registrar información de diagnóstico.

Por cierto, si esto es C ++, tu bloque catch está creando una copia del objeto de excepción que puede ser una fuente potencial de problemas adicionales. Intente capturar una referencia al tipo de excepción:

catch (const Exception& ex) { ... }


Querrá iniciar sesión en un límite de nivel. Por ejemplo, si su nivel de negocio se puede implementar en una máquina físicamente separada en una aplicación de n niveles, entonces tiene sentido iniciar sesión y lanzar el error de esta manera.

De esta forma, tiene un registro de excepciones en el servidor y no necesita hurgar en los equipos de los clientes para averiguar qué sucedió.

Utilizo este patrón en niveles comerciales de aplicaciones que usan servicios web Remoting o ASMX. Con WCF puede interceptar y registrar una excepción utilizando un IErrorHandler conectado a su ChannelDispatcher (otro tema por completo), por lo que no necesita el patrón try / catch / throw.


Si eso es lo único que hace, creo que es mejor eliminar el try / catch de esas clases y dejar que la excepción se eleve a la clase responsable de manejarlas. De esta forma, solo obtendrá un registro por excepción que le proporcionará registros más claros e incluso puede registrar la pila de modo que no se pierda el origen de la excepción.


Si tiene que registrar todas las excepciones, entonces es una idea fantástica. Dicho esto, registrar todas las excepciones sin otra razón no es una buena idea.


Use sus propias excepciones para envolver la excepción inbuild. De esta forma, puedes distinguir entre los errores conocidos y los desconocidos cuando atrapas la excepción. Esto es útil si tiene un método que llama a otros métodos que probablemente arrojen excpetions para reaccionar ante fallas esperadas e inesperadas


Este podcast de Software Engineering Radio es una muy buena referencia para las mejores prácticas en el manejo de errores. En realidad hay 2 conferencias.


Algunas veces necesita registrar datos que no están disponibles donde se maneja la excepción. En ese caso, es apropiado iniciar sesión solo para obtener esa información.

Por ejemplo (pseudocódigo Java):

public void methodWithDynamicallyGeneratedSQL() throws SQLException { String sql = ...; // Generate some SQL try { ... // Try running the query } catch (SQLException ex) { // Don''t bother to log the stack trace, that will // be printed when the exception is handled for real logger.error(ex.toString()+"For SQL: ''"+sql+"''"); throw ex; // Handle the exception long after the SQL is gone } }

Esto es similar al registro retroactivo (mi terminología), donde almacena un registro de eventos pero no los escribe a menos que haya un evento desencadenante, como una excepción lanzada.