Reputation: 4498
I'm using a crappy third party library because unfortunately I have no choice. This library creates a bunch of threads internally when I call it, and occasionally throws a NullReferenceException on one of these threads. Is there any way for me to catch these exceptions even though I don't own the thread that throws them? I have no way to change the third party code.
As a simple example to show the problem:
public static void main()
{
try
{
var crappyLib = new CrappyLibrary();
crappyLib.DoCrappyThings();
}
catch
{
Console.WriteLine("This never happens");
}
}
// I do not own the following code, I can't change it
public class CrappyLibrary
{
public void DoCrappyThings()
{
var t = new Thread(DoWork);
t.Start();
}
private void DoWork()
{
throw new ThisLibrarySucksException();
}
}
Upvotes: 2
Views: 255
Reputation: 36483
If your goal is to prevent early termination of your process because of these unhandled exceptions that are not under your control, then there exists the legacyUnhandledExceptionPolicy
setting that you can add to your app.config
that will prevent unhandled thread exceptions from terminating the whole process.
Obviously, the solution is not perfect, as unhandled exceptions can destabilize the state of the threads. But at least it's an option you can consider.
Please have a look at the documentation about this here to better understand the implications of turning on this setting.
Your app.config
would have to look something like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<legacyUnhandledExceptionPolicy enabled="1"/>
</runtime>
</configuration>
EDIT:
Just a thought, but perhaps the above setting, in combination with adding an event handler for AppDomain.UnhandledException
can help you with your need.
Using AppDomain.UnhandledException
, you can detect the failure, so that you know when you need to trigger a retry, or whatever else it is that you need to do in these cases.
And the legacyUnhandledExceptionPolicy
setting would still be useful to prevent the process from shuting down, thus giving you the opportunity to perform the retry.
Upvotes: 1
Reputation: 5369
The thing worrying me most in the described case is abnormal thread termination inside that 3rd-party lib. Once a thread is throwing, you can't catch the exception via correct way because you're not the owner of that thread invocation (and it has no idea it should propagate the exception to you; unlike it happens in TPL, let say). So even if handling such exceptions via a global handler this could be incorrect way because the lib can appear in non-consistent state after any of such exceptions.
So the safe way here is to isolate the lib inside some scope and re-launch the scope after any exception. Let say, to load the lib into separate domain.
Upvotes: 2
Reputation: 61
I hope this is helpful https://msdn.microsoft.com/en-GB/library/system.windows.forms.application.threadexception.aspx
You can try something like that (it's from the article)
Application.ThreadException += new ThreadExceptionEventHandler (ErrorHandlerForm.Form1_UIThreadException);
// Set the unhandled exception mode to force all Windows Forms errors to go through
// our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
// Add the event handler for handling non-UI thread exceptions to the event.
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Upvotes: 0