ConditionRacer
ConditionRacer

Reputation: 4498

Any way to catch an exception occurring on a thread I don't own?

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

Answers (3)

sstan
sstan

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

Yury Schkatula
Yury Schkatula

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

Stoyan Uzunov
Stoyan Uzunov

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

Related Questions