Detect on startup inside catch block

How to determine when the current executable code is called from a catch block?

void SomeFunction() { // how do I detect whether I am being called from within a catch block? } 

EDIT:

For those who requested, I wanted to implement such a class, not paying attention to the logic of the error bubbles: when I write this example code, I get a compiler error. "An exception statement without arguments is not allowed outside of catch" so that the curious destroys my idea.

 public class ErrorManager { public void OnException(Exception ex) { LogException(ex); if (IsInsideCatchBlockAlready()) { // don't destroy the stack trace, // but do make sure the error gets bubbled up // through the hierarchy of components throw; } else { // throw the error to make it bubble up // through the hierarchy of components throw ex; } } void LogException(Exception ex) { // Log the exception } bool IsInsideCatchBlockAlready() { // How do I implement this? } } 
+7
c # catch-block
source share
6 answers

Not. It is impossible to find out if, if you throw an exception, it will be caught or a program crash. You could potentially guess the compilation time with the code analysis tool, but that would not be an option while the code is running.

+3
source share

No, there is no way to do this.

Some kind of sneaky approach may come up analyzing the generated (IL) code, but I'm sure you don't want this.

This is IL from a standard console application that catches the exception:

 .method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 34 (0x22) .maxstack 1 IL_0000: nop .try { IL_0001: nop IL_0002: ldstr "OK" IL_0007: call void [mscorlib]System.Console::WriteLine(string) IL_000c: nop IL_000d: nop IL_000e: leave.s IL_0020 } // end .try catch [mscorlib]System.Exception { IL_0010: pop IL_0011: nop IL_0012: ldstr "Err" IL_0017: call void [mscorlib]System.Console::WriteLine(string) IL_001c: nop IL_001d: nop IL_001e: leave.s IL_0020 } // end handler IL_0020: nop IL_0021: ret } // end of method Program::Main 

If you can analyze that your current code (for example, in "OK" ) is inside this block, you can extract the try ... catch . This, of course, does not require calling other methods in the account.

It also sounds like a ridiculous solution to the problem you have, so before you throw yourself into something you don’t want, think about whether you really want to do it.

+2
source share

Windows CLR exceptions are another SEH. Read the Classics: Win32 β„’ Structured Exception Crash Course Crash Course . Obviously, you can detect that your code is running during the SEH handler, since an ExceptionNestedException must be detected. TEB contains everything you need if you are an OS or debugger and know how to interpret it.

For you, I highly recommend stepping back and following the documented path. If necessary, complete the registration in the try / catch blocks to avoid leakage of exceptions from the code that you do not want to throw. Make sure you handle ThreadAbortException correctly, as this is so special. Hook in Application.UnhandledException , Application.ThreadException and / or AppDomain.UnhandledException , if necessary, with proper logging and error reporting.

+1
source share

You asked the wrong question, my friend!

Most frameworks allow exception handling with a specific method. WPF, C # webforms, asp, they all have a raw exception handling routine that you can connect to at the application level.

For example, regular applications with C # formats use:

  Application.ThreadException += new ThreadExceptionEventHandler(MyCommonExceptionHandlingMethod) private static void MyCommonExceptionHandlingMethod(object sender, ThreadExceptionEventArgs t) { //Exception handling... } 

Thus, you just need to declare your class as exceptionmanager, and then include the class in exception handling, for example:

  Application.ThreadException += new ThreadExceptionEventHandler(TellMyClass) private static void TellMyClass(object sender, ThreadExceptionEventArgs t) { ExceptionManager.HandleException(sender, t); } 

However, the pattern I used is:

 public static class UnhandledExceptionManager { Logger _logger; public static void RegisterToHandleFormsException(){ _logger = new Logger(); Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); Application.ThreadException += OnThreadException; AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; } public static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e){ HandleException((Exception)e.ExceptionObject); } private static void HandleException(Exception exception, [CallerMemberName] string methodName = "") { try { _logger.Error(methodName, exception); } catch (Exception e) { Debug.WriteLine("({0}) {1}", methodName, e); } } } 

What is used in Program.cs:

 public static void Main(){ UnhandledExceptionManager.RegisterToHandleFormsException(); //etc } 
0
source share

As indicated in other answers, you cannot. You can fake it by passing a parameter to a method, but that sounds like the smell of code.

0
source share

You can always do it easily:

 void SomeFunction(bool isCalledFromCatch) { // how do I detect whether I am being called from within a catch block? } try { } catch(...) { SomeFunction(true); } 
0
source share

All Articles