How to Propagate Exceptions Between Threads

How can I propagate exceptions between threads?

C++11 introduced the exception_ptr type that allows to transport exceptions between threads:

#include<iostream>
#include<thread>
#include<exception>
#include<stdexcept>

static std::exception_ptr teptr = nullptr;

void f()
{
try
{
std::this_thread::sleep_for(std::chrono::seconds(1));
throw std::runtime_error("To be passed between threads");
}
catch(...)
{
teptr = std::current_exception();
}
}

int main(int argc, char **argv)
{
std::thread mythread(f);
mythread.join();

if (teptr) {
try{
std::rethrow_exception(teptr);
}
catch(const std::exception &ex)
{
std::cerr << "Thread exited with exception: " << ex.what() << "\n";
}
}

return 0;
}

Because in your case you have multiple worker threads, you will need to keep one exception_ptr for each of them.

Note that exception_ptr is a shared ptr-like pointer, so you will need to keep at least one exception_ptr pointing to each exception or they will be released.

Microsoft specific: if you use SEH Exceptions (/EHa), the example code will also transport SEH exceptions like access violations, which may not be what you want.

How to propagate exception from thread in java?

Use FutureTask http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/FutureTask.html#get%28%29 . It's get methods will encapsulate any exceptions from the task that might have run on another thread.

ExecutionException: Exception thrown when attempting to retrieve the result of a task that aborted by throwing an exception. This exception can be inspected using the Throwable.getCause() method.

Exception propagation across threads?

Propagation is not automatic with thread. If a thread throws, and that exception is not caught, the program terminates no matter what.

future and shared_future will store an uncaught exception in the child thread. That exception is then automatically propagated when get is called.

Exception propagation in Java parallel streams

The main difference is that while the individual Stream intermediates can run in parallel, they are only evaluated when the terminal operation is encountered; that makes it a virtual join point.

Ie, the same would be possible with something like

try {
Thread concurrent = new Thread(runnable);
concurrent.start();
concurrent.join();
} catch (ExceptionThrownInThread ex) {}

However, in the general case - and that's pretty much Akka's programming model - you have

yourMessenger.registerCallbacks(callbacks);
new Thread(yourMessenger).start();

Now, the callbacks will eventually be called from within the thread you created, but there is no structure to wrap around its execution as a whole; so who would catch this exception?

I don't know Akka enough, but in projectreactor's Publishers, you can register an error handler, as in

Mono<Result> mono = somethread.createResult().onError(errorHandler);

But again, in the general case it's not trivial.

Curious exception propagation to main thread

If you only call stop() on the second one then the for loop waits forever for the first one to complete. The exception hasn't been swallowed; it has been captured and will be thrown if and when your program calls get() on the second future, but your program has hung waiting for the first future and will not reach that point.

How to propagate an Exception from a Task / Thread to the method that created this Task in c#?

The easiest way for you to propagate an exception from a Task executed on the thread-pool is to turn it to actually return a Task which you can await on:

public async Task AwaitOnTaskAsync()
{
try
{
await DoStuffWithThreadAsync();
}
catch (Exception e)
{
}
}

public Task DoStuffWithThreadAsync()
{
return Task.Run(() => { throw new Exception("blabla"); });
}

await will make sure to unwrap the exception out of the Task, allowing you to apply a try-catch on it.

Side Note - Don't use the Task constructor, instead use Task.Run to return a "hot task" (one which has already started). There's no point in creating a Task which you're actively blocking on using Thread.Sleep later on, either execute it synchronously or use async-await to asynchronously wait on the task.

How to catch an Exception from a thread

Use a Thread.UncaughtExceptionHandler.

Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread th, Throwable ex) {
System.out.println("Uncaught exception: " + ex);
}
};
Thread t = new Thread() {
@Override
public void run() {
System.out.println("Sleeping ...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted.");
}
System.out.println("Throwing exception ...");
throw new RuntimeException();
}
};
t.setUncaughtExceptionHandler(h);
t.start();


Related Topics



Leave a reply



Submit