1

To catch any uncaught exception, I'm subscribing a Handler in the Main-Method() like so:

Application.ThreadException += Application_ThreadException;
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

This works perfectly fine and catches ANY unhandled exception (EXCEPT StackOverflowException), whether it's a UI-Thread or a Background-Thread Exception. (Only used for logging / Error Reporting, like this:)

private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
    //Log exception
    Log.e("Unhandled Background Thread Exception", e.Exception);

    //Show oops.
    ExceptionHandler eh = new ExceptionHandler();
    eh.Exception = e.Exception;
    eh.ShowDialog();
    eh.Dispose();
}

private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    //Log exception
    Log.e("Unhandled UI Thread Exception", (Exception)e.ExceptionObject);

    //Show oops.
    ExceptionHandler eh = new ExceptionHandler();
    eh.Exception = (Exception)e.ExceptionObject;
    eh.ShowDialog();
    eh.Dispose();
}

However, to trace down a problem it usually helps to figure out, what the user was doing BEFORE the exception appeared... So, I was wondering if there is an "equal" way, to subscribe to any other event within the application?

i.e. something like a global event:

Application.EveryButtonClick += Application_ButtonClicked;

...

private static void Application_ButtonClicked(Object sender, Args e, Method calledMethod){
   Log.Trace("User clicked on " + ((Button)sender).Name);

   calledMethod.Invoke(sender, e);
}

Or something that's called an Interceptor in Java-EE (Handled through Annotations)?

@AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception {

 logger.debug("LoggingInterceptor - before EJB method invoke: "
    + ctx.getMethod().getName());

 Object result = ctx.proceed(); //<-- Call initial method

 logger.debug("LoggingInterceptor - after EJB method invoke: " 
    + ctx.getMethod().getName() + " Call result was: " + result.toString());

 return result;
}

Or something similar? There are quite some "events" I would like to track from a "global" point of view...


The example is quite "small" and buttons aren't that hard to handle.

But maybe I need a global "Listview_selected_index_changed(object sender, args e, Method invokedMethod )" handler?

dognose
  • 20,360
  • 9
  • 61
  • 107
  • 2
    *"This works perfectly fine and catches ANY unhandled exception"* It does not catch `StackOverflowException`. – Ron Beyer Apr 25 '18 at 18:19
  • @RonBeyer You're right - but I don't mind about these :-) – dognose Apr 25 '18 at 18:20
  • Is this WPF or Winforms? – Ron Beyer Apr 25 '18 at 18:20
  • @RonBeyer WinForms. – dognose Apr 25 '18 at 18:20
  • The stack trace should tell you what the user was doing prior to the exception being raised. For example, if the exception was raised inside a button click event handler, then that method name should appear in the stack trace. – Chris Dunaway Apr 25 '18 at 18:22
  • @ChrisDunaway Yes, the location in the Stacktrace is known (Along with the pdb-file) - However, Some "Exceptions" are very context sensitive.... I.e. they only appear if the user clicked on button "X" prior to clicking on button "Y"... – dognose Apr 25 '18 at 18:24
  • 1
    +1 for novelty. I found no duplicate, only a related thread - [would this help?](https://stackoverflow.com/a/4279826/1132334) – Cee McSharpface Apr 25 '18 at 18:30
  • @dognose I think a good way to do that would be to have the user "opt-in" to a session recording and then use something like Log4Net with a more verbose output and add logging to all your methods. There are even [Fody extensions that can help](https://github.com/csnemes/tracer). – Ron Beyer Apr 25 '18 at 18:32
  • @dlatikay That *might* help - however before digging into Win32-Api Ways, let's see, what other options are out there :-) – dognose Apr 25 '18 at 18:34
  • insufficient time, just a rough draft: a) winforms framework does not contain a global event hook mechanism [except for vb6/activex/com interoperability](https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Control.cs,17373), and I presume you don't want to go there... so b) I would write a public static helper method that takes a `Form`, and hooks up a handler to events of each control on that form you're interested in. call in load, store n most recent in a queue and dump sequence of event and control names as your global exception handler fires. – Cee McSharpface Apr 25 '18 at 18:59
  • @dlatikay That will work (i'm sure) - But I refuse to beleive there isn't a more convenient way in "LINQ-ages".... – dognose Apr 25 '18 at 19:03
  • There are analogs of Interceptors, but how would that help? What would you decorate with them? – Evk Apr 25 '18 at 19:04

0 Answers0