The error of `ThreadHandle::join` isn't Sync, which makes it incompatible with `eyre::Report`. What is the best way to handle this in library crates?

I have built a library crate that uses ThreadHandle::join, and returns the error, if it fails (which is Box<dyn Any + Send + 'static>>).

The problem is, eyre::Report and similar types require errors to be Sync.

The end result is, that the error of my library is painful to use with those craters (especially, if the error is deep within an error tree).

I'm wondering what the best solution for my library crate would be in this case.

For now, I have wrapped the error of ThreadHandle::join in Arc<Mutex<_>>, which works. But I doubt this is the ideal solution.

Another option would be, to let the user of my crate do the above. However, as mentioned, this would kill ergonomics of handling the error.

I'm also wondering why ThreadHandle::join isn't returning an error that's Sync.

You can wrap the error in sync_wrapper::SyncWrapper which provides a trivial into_inner function. SyncWrapper is always Sync, but you can't get a &T from a &SyncWrapper<T>

2 Likes

Thanks, @RustyYato!

The main benefit of SyncWrapper compared to Arc<Mutex<_>> is performance, right?

I should have mentioned that performance isn't important here. The thread my crate is joining is a server, and it's very unlikely that the error will occur. And even if it does, end-users most likely will just report the error and exit.

My main "problem" with Arc<Mutex<_>> is that it seems very strange (I have never seen this before).

So would Arc<Mutex<_>> be indeed the best solution here? (To avoid an additional dependency).

If you want to avoid the dep then, you can probably get away with just Mutex (if you don't need to share the error). Otherwise yes, Arc<Mutex<_>> is the best option. But it's a tiny dep, so I wouldn't worry about it.

Oh, you are right, Mutex alone is enough. Thanks again!

I'll keep SyncWrapper in mind, in case I have a similar scenario where performance is important.