CurrentDomain.UnhandledException is not being thrown in Windows Service - c#

I've setup the UnhandledException to log any exceptions before my service crashes.
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(unhandledException);
I'm testing this by throwing and unhandled exception.
throw new Exception("TestExcepion");
private void unhandledException(object sender, UnhandledExceptionEventArgs e)
{
// Logs to Log4Net but its not reaching here.
Log.Info("Unhandled Exception: " + (e.ExceptionObject as Exception).ToString());
}
I'm attempting to log this within my unhandledException method using Log4Net but im getting nothing.
Why isn't the exception being caught?

It is probably that your throwing code is before use set AppDomain.CurrentDomain.UnhandledException or because you put it in OnStart method
Second option is because it is ThreadException.
Bot above problems were discussed before in following threads:
How can I set up .NET UnhandledException handling in a Windows service?
Global exception handler for windows services?

Related

How do I handle an exception thrown by a COM library from a worker thread?

I am building a .Net application which is using a COM library (I am really bad at COM, but its a library which I need to register using regsvr32 and once referenced in visual studio it says the file type is ActiveX).
In a console application, I am creating a new COM object like this :
static void Main(string[] args)
{
var comObj = new EikonDesktopDataAPI();
comObj.OnStatusChanged += EikonDesktopDataApi_OnStatusChanged;
comObj.Initialize();
Console.ReadLine();
}
private void EikonDesktopDataApi_OnStatusChanged(EEikonStatus status)
{
try{
throw new Exception("An exception 1.");
}catch(Exception ex){
throw new Exception("Tell the main thread." , ex);
}
}
So the application initialise the Api synchronously on the Main thread and wait on Console.ReadLine(). After a few seconds the EikonDesktopDataApi_OnStatusChanged event is triggered. When debugging, I can see that this is handled on a worker thread. As the exception is thrown on another thread, the console application doesn't crash. How can I catch this exception?
I tried to add the SLAThreadAttribute on the Main method, but this cause the event to never be raised.
I also tried to use :
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
But the exception is not handled neither.
The only way I found to "catch" the exception was to use :
AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
But this cause the handler method to handle 3 exceptions: "An exception 1", then "Tell the main thread." and finally a "Exception has been thrown by the target of an invocation". Which means I will handle even "caught" exception which is impractical.
Any ideas?
EDIT:
I did a WPF application, where I am instantiating the COM object from the main thread. Once initialized the event is raised and my event handler runs on the MAIN thread, but if I throw an exception, it wont crash the application or raise an Unhandledexception event. I really don't understand why exceptions thrown on the main thread just does nothing.

How to catch all unhandled exceptions in WinForms application correctly

I want to set the handler method for all unhandled exceptions from any threads in my WinForms application. I don't create any application domains by myself.
According to UnhandledException documentation, I need to set UnhandledExceptionMode.ThrowException mode via Application.SetUnhandledExceptionMode method to catch main thread's exceptions too:
In applications that use Windows Forms, unhandled exceptions in the
main application thread cause the Application.ThreadException event to
be raised. If this event is handled, the default behavior is that the
unhandled exception does not terminate the application, although the
application is left in an unknown state. In that case, the
UnhandledException event is not raised. This behavior can be changed
by using the application configuration file, or by using the
Application.SetUnhandledExceptionMode method to change the mode to
UnhandledExceptionMode.ThrowException before the ThreadException event
handler is hooked up. This applies only to the main application
thread. The UnhandledException event is raised for unhandled
exceptions thrown in other threads
So, the resulting code will look like the following:
public static void UnhandledExceptionEventHandler(object sender, UnhandledExceptionEventArgs e)
{
// ...
}
[STAThread]
static void Main(string[] args)
{
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionEventHandler);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm(pathToCheck));
}
Is it ok? Will it catch all unhandled exceptions from any threads (including the main thread, UI thread and all threads created by Task class)? Did I understand the documentation correctly?
Yes, I saw questions like this here, but I don't understand why should I also use the following code:
Application.ThreadException += new
ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);
You should subscribe both events. Note that even this will not catch automatically everything from other threads. For example, when delegates are invoked asynchronously, the exception will be propagated to the caller thread only when EndInvoke is called.
[STAThread]
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException +=
(sender, args) => HandleUnhandledException(args.ExceptionObject as Exception);
Application.ThreadException +=
(sender, args) => HandleUnhandledException(args.Exception);
}
static void HandleUnhandledException(Exception e)
{
// show report sender and close the app or whatever
}

AppDomain.CurrentDomain.UnhandledException does not get called

I have a WCF service that has the following code in Global.asax:
protected void Application_Start(object sender, EventArgs e)
{
// Make sure that any exceptions that we don't handle at least get logged.
AppDomain.CurrentDomain.UnhandledException += LogUnhandledException;
}
private void LogUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Log.Error.LogException("UnhandledException", e.ExceptionObject as Exception);
}
The idea is to at least log all exceptions that are unhanded.
But it does not seem to ever be called. I tried doing a Divide by Zero in one of my service operations and it just stops the service after it hits the exception.
int zero = 0;
int result = 100 / zero;
The LogUnhandledException method never gets called.
I have tried this in both IIS and running in the debugger.
How can I get this event to work for a WCF service?
The unhandled exception filter for an app domain is a last-ditch attempt to allow the application to log meaningful information before it is terminated.
This event provides notification of uncaught exceptions. It allows the application to log information about the exception before the system default handler reports the exception to the user and terminates the application.
If WCF allowed an exception thrown by a service to be completely unhandled in this way it would mean that when the service is hosted in IIS the entire worker process would be terminated because a single request raised an exception - not a desirable outcome. As a result WCF doesn't leave exceptions thrown by services unhandled - this event will not be raised in this case.
If you want to log exceptions thrown by WCF services then take a look at the IErrorHandler interface instead.
Try also catching a ThreadException, e.g.
Application.ThreadException += Application_ThreadException;
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
I had the same issue in the WinForms app a while ago. UnhandledException is raised for truly unhandled exceptions that would normally terminate your entire process immediately. Typically there's a global handler that doesn't let that happen, and provides some default behavior. So you need to catch the exception before it goes to that handler. This can be done via a ThreadException.
Have you tried this?
From http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(LogUnhandledException);
I'm wondering what is difference between your call and this one, with the "+= new"... but it's worth the try.

How to make Elmah work with UnobservedTaskException

I'm developing a asp.net mvc application. The architecture of my application as below:
a DBAccessLayer //layer for accessing database
a ServiceLayer //layer to connect 1 and 3.
a WebLayer //Web UI layer
I want to log all application exceptions including the exceptions in the TaskScheduler.UnobservedTaskException event.
I've tested to do as below:
protected void Application_Start()
{
...
TaskScheduler.UnobservedTaskException += (object sender, UnobservedTaskExceptionEventArgs excArgs) =>
{
ErrorSignal.FromCurrentContext().Raise(excArgs.Exception);
excArgs.SetObserved();
};
}
but when the UnobservedTaskException event is fired, the application crashed with exception as below:
System.ArgumentNullException was unhandled
Message=Value cannot be null.
Parameter name: context
Source=Elmah
ParamName=context
StackTrace:
at Elmah.ErrorSignal.FromContext(HttpContext context) in c:\builds\ELMAH\src\Elmah\ErrorSignal.cs:line 67
at MyMvcApplication.<Application_Start>b__0(Object sender, UnobservedTaskExceptionEventArgs excArgs) in ...\Global.asax.cs:line 82
at System.Threading.Tasks.TaskScheduler.PublishUnobservedTaskException(Object sender, UnobservedTaskExceptionEventArgs ueea)
at System.Threading.Tasks.TaskExceptionHolder.Finalize()
Additionally, I put the UnobservedTaskException event in the global.asax.cs of WebLayer, can it be fired when the DBAccessLayer and ServiceLayer have unobserved exceptions?
Thanks.
It looks like when your handler gets fired, there isn't an HttpContext because the scheduled task is not running as part of an HTTP request. Instead of using
ErrorSignal.FromCurrentContext().Raise
you could use
ErrorLog.GetDefault(null).Log

Why isn't my exception being caught

I have an application that is mixed Winforms and WPF. In Winforms, I have a global exception handler that is defined as follows:
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
Application.ThreadException += Application_ThreadException;
This ALWAYS catches exceptions anywhere in my application that occur that are not expected and handled gracefully.
For WPF, all I seem to be able to capture is:
wpfAppDomain = new System.Windows.Application();
wpfAppDomain.DispatcherUnhandledException +=
wpfAppDomain_DispatcherUnhandledException;
This does NOT always catch global exceptions, and I often find that exceptions are swallowed somewhere and I'm not sure why.
How can I make a global exception handler for WPF that can catch any exception that occurs that is unhandled?
There are several cases where this code will not catch an exception and do so by design
The exception is simply uncatchable. For example a runtime thrown StackOverflowException
The exception is unhandled in your code, but caught in the core WPF framework.
There is no way to catch all thrown exceptions. To do so would allow you to violate semantics of code that should always work.
Have you tried this after calling SetUnhandledExceptionMode? Like this:
// Force all exceptions through our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
DispatcherUnhandledException only catches exception from code called by a dispatcher (like the name suggests), it is supposed to catch exceptions thrown when called from WPF code.
It does not cover exceptions thrown from: WinForms, BackgroundWorker, the thread pool or threads you started yourself.
you can still use AppDomain.CurrentDomain.UnhandledException to catch those.

Categories