2011-01-04 24 views
16

Mi código es el siguiente.Cómo obtener el nombre del método que causó la excepción

try 
{ 
    _productRepo.GetAllProductCategories(); 
} 
catch (Exception ex) 
{ 
    //Do Something 
} 

Necesito una manera de mostrar el nombre del método, supongamos que en el caso anterior, si ninguna excepción en las GetAllProductCategories() método, que necesito para obtener este nombre del método es decir, "GetAllProductCategories()" como el resultado de mi . ¿Alguien puede sugerirme cómo hacer esto?

+1

¿La respuesta simple? Es el método en la parte superior de la pila de llamadas. Este es el método que se llamó más recientemente antes de que se produjera la excepción. :) – Chiramisu

+0

Lo resolví al marcar esta respuesta http://stackoverflow.com/questions/27997276/get-method-name-that-threw-exception –

Respuesta

1

Mire la stacktrace.

Es una propiedad en la excepción.

20

Hay una propiedad TargetSite en System.Exception que debería ser útil.

Obtiene el método que arroja la excepción actual .

En su caso, es probable que desee algo como:

catch (Exception ex) 
{ 
    MethodBase site = ex.TargetSite; 
    string methodName = site == null ? null : site.Name; 
    ...   
} 

Vale la pena señalar algunas de las cuestiones que se enumeran:

Si el método que lanza esta excepción no está disponible y la traza de la pila no es una referencia nula (Nothing en Visual Basic), TargetSite obtiene el método de la pila traza. Si el seguimiento de la pila es una referencia nula , TargetSite también devuelve una referencia nula .

Nota: La propiedad TargetSite puede no informar con precisión el nombre del método en el que un excepción fue lanzado si el manejador de excepciones maneja una excepción a través límites del dominio de aplicación.

Usted puede utilizar la propiedad como StackTrace @leppie sugiere también, pero tenga en cuenta que se trata de una representación de cadena de los marcos de la pila; por lo que deberá manipular si solo desea el nombre del método que arrojó la excepción.

3

Está en la StackFrame ...

private string GetExecutingMethodName() 
{ 
    string result = "Unknown"; 
    StackTrace trace = new StackTrace(false); 
    Type type = this.GetType(); 

    for (int index = 0; index < trace.FrameCount; ++index) 
    { 
     StackFrame frame = trace.GetFrame(index); 
     MethodBase method = frame.GetMethod(); 

     if (method.DeclaringType != type && !type.IsAssignableFrom(method.DeclaringType)) 
     { 
      result = string.Concat(method.DeclaringType.FullName, ".", method.Name); 
      break; 
     } 
    } 

    return result; 
} 

Este método fue escrito para una clase de controlador de registro y el uso de GetType() simplemente elimina los métodos dentro de la clase de controlador de registro sea devuelta como la ejecución de la última método. Como la clase de controlador de registro se escribió para más que solo registrar excepciones, se requirió un nuevo objeto de StackTrace. Obviamente, para encontrar "el método que lanzó la excepción" GetType() podría no ser necesario.

Si solo quieres la parte superior de la pila, toma el primer cuadro, llama a GetMethod() y devuelve eso, o simplemente usa TargetSite. GetType() podría ser eliminado. También tenga en cuenta que la Excepción debería pasarse para crear el objeto StackTrace. Por ejemplo:

class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      Test(); 
     } 
     catch (Exception ex) 
     { 

      // does not work properly - writes "Main" 
      Console.WriteLine(MethodBase.GetCurrentMethod()); 

      // properly writes "TestConsole.Program.Test" 
      Console.WriteLine(GetExecutingMethodName(ex)); 

      // properly writes "Test" 
      Console.WriteLine(ex.TargetSite.Name); 
     } 

     Console.ReadKey(); 
    } 


    static void Test() 
    { 
     throw new Exception("test"); 
    } 

    private static string GetExecutingMethodName(Exception exception) 
    { 
     var trace = new StackTrace(exception); 
     var frame = trace.GetFrame(0); 
     var method = frame.GetMethod(); 

     return string.Concat(method.DeclaringType.FullName, ".", method.Name); 
    } 
} 

Básicamente, si TargetSite() hace lo que usted desea, entonces no continúe.Pero, muchas veces en los controladores de registro, un objeto de excepción no está disponible (es decir, rastreo y auditoría) por lo que es necesario un nuevo objeto StackTrace() para recuperar el último método ejecutado, el anterior ANTES del método de registro.

+0

¿A qué se refiere GetType? ¿Es este otro método que creaste? El GetType incorporado necesita un objeto de referencia. – KingOfHypocrites

+0

@KingOfHypocrites - GetType() se llama desde la clase actual. –

+0

No veo cómo esto se aplica a la pregunta formulada. Este código genera un objeto 'StackTrace' completamente nuevo, no relacionado con el seguimiento de la pila de la excepción. Además, .NET ya tiene una forma perfectamente buena (y más confiable) de obtener el objeto 'MethodInfo' para el método que se está ejecutando actualmente: [' MethodBase.GetCurrentMethod'] (http://msdn.microsoft.com/en-us/ library/system.reflection.methodbase.getcurrentmethod (v = vs.110) .aspx) –

Cuestiones relacionadas