2009-05-26 11 views
8

¿Es posible lanzar una excepción (podría ser una excepción) con un seguimiento de pila personalizado?Throw Exceptions with custom stack trace

Como ejemplo concreto: digamos que tengo un conjunto de algunos pequeños métodos de utilidad estáticos que pueden arrojar excepciones. Sin embargo, me gustaría que la excepción parezca haberse originado a partir del método anterior en lugar del método de utilidad (quiero ignorar el primer fotograma de la traza).

Respuesta

3

Jugar con el rastro de la pila realmente no suena como una buena idea, incluso si es posible (estoy dudoso de eso). Dime, ¿por qué querrías hacer eso de todos modos? El propio .NET Framework (el BCL) a menudo usa métodos de utilidad estáticos para lanzar excepciones, de la forma en que usted sugiere (ThrowHelper es su nombre en al menos algunas partes del marco), y ciertamente esconde cualquier cosa en el seguimiento de la pila.

He aquí un ejemplo seguimiento de la pila de una prueba que acaba de ejecutar:

 
    at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) 
    at System.ThrowHelper.ThrowArgumentOutOfRangeException() 
    at System.Collections.Generic.List`1.get_Item(Int32 index) 
    at HelloWorld.Program.Main(String[] args) in C:\...\Program.cs:line 23 
    at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) 
    at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart() 

Como se puede ver, el BCL utiliza el método ThrowArgumentOutOfRangeException, y es claramente visible en el seguimiento de la pila. Si desea marcar el método de ayuda con el atributo DebuggerNonUserCode, entonces me parece justo (aunque no se hace en el BCL).

+0

Supongo que tienes razón en realidad. La razón principal por la que quería hacer esto era para "ponerme al día" depurando estas excepciones cuando se lanzan. Sin embargo, creo que la mejor manera de lograr lo que quiero es usar el atributo [DebuggerNonUserCode] en mis métodos. –

+0

Sí, veo exactamente de dónde vienes. Los métodos .NET helper no usan el atributo DebuggerNonUserCode, pero me parece una idea sensata. – Noldorin

12

La propiedad de StackTrace es virtual: cree su propia clase de Excepción derivada y haga que la propiedad devuelva lo que desee.

+0

Haría esto, excepto que preferiría arrojar el tipo de excepción original. Y no quiero pasarlo por alto como una excepción interna. –

+0

Puede hacer que su propia excepción herede de muchas (tal vez todas) las excepciones normales, de modo que su excepción personalizada, con un StackTrace personalizado, podría ser atrapada por un bloque catch para una excepción estándar. – supercat

+0

La razón por la que esto no funciona muy bien es porque la implementación base de ToString en Exception no usa la propiedad StackTrace, sino que llama al método privado GetStackTrace (que es lo que llama la propiedad StackTrace), por lo que su anulación es inútil con respecto al comportamiento predeterminado. Una decisión de diseño muy desafortunada que estoy seguro de que no pueden cambiar en este punto. – MarkPflug

Cuestiones relacionadas