una - try catch en c# asp net
Manejando excepciones, ¿es esta una buena manera? (7)
Este es un enfoque bastante común para resolver el problema de manejo de excepciones (de más específico a menos específico).
Solo tenga en cuenta que tener una excepción genérica de aplicación específica para capturar todo lo que sucede en esa aplicación / método no es una gran idea si quiere detectar problemas específicos. Eventualmente intente extenderlo con excepciones más específicas.
Retirar excepciones es bueno, es mejor declarar el método para lanzar ciertas excepciones y permitir que los llamadores las manejen. De esta forma, deberá crear menos código y podrá centralizar algunos controles.
Estamos luchando con una política para manejar correctamente las excepciones en nuestra aplicación. Estos son nuestros objetivos (resumidos):
- Manejar solo excepciones específicas.
- Maneje solo las excepciones que puede corregir
- Registra solo una vez
Hemos presentado una solución que implica una Excepción específica de la aplicación genérica y funciona así en un fragmento de código:
try {
// Do whatever
}
catch(ArgumentNullException ane)
{
// Handle, optinally log and continue
}
catch(AppSpecificException)
{
// Rethrow, don''t log, don''t do anything else
throw;
}
catch(Exception e)
{
// Log, encapsulate (so that it won''t be logged again) and throw
Logger.Log("Really bad thing", e.Message, e);
throw new AppSpecificException(e)
}
Todas las excepciones se registran y luego se convierten en una excepción AppSpecificException para que no se vuelva a registrar. Finalmente llegará al controlador de eventos de último recurso que se ocupará de él si es necesario.
No tengo mucha experiencia con patrones de manejo de excepciones ... ¿Es esta una buena manera de resolver nuestros objetivos? ¿Tiene algún inconveniente importante o grandes advertencias rojas?
Nota: Uno de los inconvenientes de esto es que después de la primera captura, usted pierde la capacidad de manejar una excepción específica (si llama a un método que llama a otro método y el segundo arroja una excepción, no puede manejarlo), pero He descubierto que nunca he hecho esto de ninguna manera ... Solo manejo excepciones con un nivel de profundidad ...
Intente evitar crear una nueva excepción y volver a lanzar, ya que lanzar una excepción establece el seguimiento de la pila donde se lanzó la excepción. Solo haz un tiro simple. Ver Demasiada reutilización en el blog de Eric Lippert.
No registre una excepción y luego vuelva a lanzarla; es responsabilidad de quienes llaman manejar / registrar cualquier excepción que genere.
Solo capture una excepción para manejarla (por ejemplo, para registrarla), o agregue información específica de contexto.
Primera opción para resolver el problema de seguimiento de la pila:
class AppSpecificException : ApplicationException
{
public string SpecificTrace { get; private set; }
public string SpecificMessage { get; private set; }
public AppSpecificException(string message, Exception innerException)
{
SpecificMessage = message;
SpecificTrace = innerException.StackTrace;
}
}
Tuve que escribir un ejemplo para entender la pregunta y verificar el problema de stacktrace, este es el código para mí, poner atención al método button2_click, finalmente mi cuadro de texto muestra la cadena de bloqueo y la stacktrace:
private String internalValue;
private void Operation1(String pField)
{
if (pField == null) throw new ArgumentNullException("pField");
internalValue = pField;
}
private void Operation2(Object pField)
{
if (pField == null) throw new ArgumentNullException("pField");
internalValue = Convert.ToInt32(pField).ToString();
}
private void Operation3(String pField)
{
if (pField == null) throw new ArgumentNullException("pField");
internalValue = pField;
Operation2(-1);
}
/// <exception cref="AppSpecificException"><c>AppSpecificException</c>.</exception>
private void button1_Click(object sender, EventArgs e)
{
try
{
Operation1("One");
Operation2("Two");
Operation3("Three");
MessageBox.Show(internalValue);
}
catch (ArgumentNullException ex)
{
textBoxException.Text = ex.Message + (char) 13 + (char) 10 + ex.StackTrace;
}
catch (AppSpecificException ex)
{
//textBoxException.Text = ex.Message + (char)13 + (char)10 + ex.StackTrace;
throw;
}
catch (Exception ex)
{
textBoxException.Text = ex.Message + (char)13 + (char)10 + ex.StackTrace;
throw new AppSpecificException("crash", ex);
}
}
private void button2_Click(object sender, EventArgs e)
{
try
{
button1_Click(sender, e);
}
catch (AppSpecificException ex)
{
textBoxException.Text = ex.SpecificMessage + (char) 13 + (char) 10 + ex.SpecificTrace;
}
}
Recomiendo pensar más en qué patrones quieres usar para "entregar"
Si sus patrones de manejo descienden para iniciar sesión o volver a lanzar, entonces el error retroprown eventualmente se registrará. Entonces, al final, es solo registro de errores. Si usa ASP.NET use elmah para que al menos su código no esté cubierto con la placa try / catch-and-log de la caldera.
Hay solo algunas formas de "manejar" los errores que no terminan en el mero registro.
Rever. (Cuidado con los bucles infinitos)
Espera y vuelve a intentarlo.
Pruebe una técnica diferente pero equivalente (¿No se puede conectar en http? Try conectándose en https).
Establezca las condiciones faltantes (cree la carpeta que arrojó la FolderNotFoundException)
Ignore el error. Piénselo dos veces, solo tiene sentido cuando el error no es realmente un problema, por ejemplo, si una biblioteca de terceros le advierte sobre una condición que no se aplica.
Si registra la excepción demasiado cerca de la hora en que se lanzó por primera vez, no estará registrando el seguimiento completo de la pila.
Manejar excepciones (es decir, corregirlas), lo más cerca posible de cuando fueron lanzadas. Reúna información sobre el contexto tan pronto como sea posible para cuando fueron lanzados. Pero permita que las excepciones se propaguen hasta donde realmente puedan manejarse. El registro es un tipo de manejo de último recurso, por lo que debería ocurrir en las capas externas de los subsistemas de aplicaciones.
Esto debería eliminar la necesidad de una excepción específica de la aplicación utilizada como marcador para no registrar una excepción que no debería haber sido capturada para comenzar.
Una buena solución sobre el manejo de excepciones es el uso de Interceptación. Sin embargo, debe validar si este patrón se puede aplicar a su aplicación dependiendo de la arquitectura: la interceptación requiere un contenedor.
El principio es factorizar su manejo de excepciones fuera de los métodos usando atributos (personalizados) en ellos y luego usar el contenedor para inicializar sus instancias. El contenedor procesará las instancias de tesis por reflexión: se llama interceptores de instancias. Simplemente tendrá que llamar a sus métodos como de costumbre a través de estas instancias y dejar que el mecanismo de interceptación haga el trabajo que codificó antes o después del método.
Tenga en cuenta que puede agregar try catch en los métodos para administrar excepciones específicas que no están administradas en sus interceptores.
Intercepción de Unity: http://msdn.microsoft.com/en-us/library/dd140045.aspx