utilizar - que tipos de excepciones existen en c#




¿Cuál es la forma correcta de volver a lanzar una excepción en C#? (6)

Depende. En una compilación de depuración, quiero ver el seguimiento de la pila original con el menor esfuerzo posible. En ese caso, "tirar"; encaja a la perfección. Sin embargo, en una versión de lanzamiento, (a) quiero registrar el error con el seguimiento de pila original incluido, y una vez hecho esto, (b) remodelar el manejo de errores para que tenga más sentido para el usuario. Aquí "Lanzar Excepción" tiene sentido. Es cierto que volver a generar el error descarta el seguimiento de la pila original, pero un desarrollador no obtiene nada al ver la información de seguimiento de la pila, por lo que está bien volver a emitir el error.

        void TrySuspectMethod()
        {
            try
            {
                SuspectMethod();
            }
#if DEBUG
            catch
            {
                //Don't log error, let developer see 
                //original stack trace easily
                throw;
#else
            catch (Exception ex)
            {
                //Log error for developers and then 
                //throw a error with a user-oriented message
                throw new Exception(String.Format
                    ("Dear user, sorry but: {0}", ex.Message));
#endif
            }
        }

La forma en que está redactada la pregunta, que enfrenta a "Throw:" frente a "Throw ex;" hace que sea un poco de arenque rojo. La elección real es entre "tirar"; y "Lanzar excepción", donde "Lanzar ex"; Es un caso especial poco probable de "Excepción de tiro".

Esta pregunta ya tiene una respuesta aquí:

Tengo una pregunta para usted que proviene de que mi pareja hace las cosas de una manera diferente a la que yo hago.

¿Es mejor hacer esto?

try
{
    ...
}
catch (Exception ex)
{
    ...
    throw;
}

o esto:

try
{
    ...
}
catch (Exception ex)
{
    ...
    throw ex;
}

¿Hacen lo mismo? ¿Es uno mejor que el otro?


Descubrí que si la excepción se produce en el mismo método que se captura, el seguimiento de pila no se conserva, por lo que vale.

void testExceptionHandling()
{
    try
    {
        throw new ArithmeticException("illegal expression");
    }
    catch (Exception ex)
    {
        throw;
    }
    finally
    {
        System.Diagnostics.Debug.WriteLine("finally called.");
    }
}

El primero es mejor. Si intenta depurar el segundo y mira la pila de llamadas, no verá de dónde proviene la excepción original. Hay trucos para mantener intacta la pila de llamadas (intente buscar, se ha respondido antes) si realmente necesita volver a lanzar.


Mis preferencias es usar

try 
{
}
catch (Exception ex)
{
     ...
     throw new Exception ("Put more context here", ex)
}

Esto conserva el error original, pero le permite poner más contexto, como un ID de objeto, una cadena de conexión, cosas así. A menudo, mi herramienta de informes de excepciones tendrá 5 excepciones encadenadas al informe, cada una con más detalles.


Si lanza una excepción sin una variable (el segundo ejemplo), StackTrace incluirá el método original que lanzó la excepción.

En el primer ejemplo, el StackTrace se cambiará para reflejar el método actual.

Ejemplo:

static string ReadAFile(string fileName) {
    string result = string.Empty;
    try {
        result = File.ReadAllLines(fileName);
    } catch(Exception ex) {
        throw ex; // This will show ReadAFile in the StackTrace
        throw;    // This will show ReadAllLines in the StackTrace
    }

Siempre debe usar la siguiente sintaxis para volver a generar una excepción; de lo contrario, pisará el seguimiento de pila:

throw;

Si imprime la traza resultante de "throw ex", verá que termina en esa declaración y no en la fuente real de la excepción.

Básicamente, debe considerarse un delito penal usar "lanzar ex".





exception-handling