use std::{ future::Future, pin::Pin, sync::Mutex, task::{Context, Poll}, }; pub(crate) struct CatchUnwindFuture { future: Mutex, } pub(crate) fn catch_unwind(future: F) -> CatchUnwindFuture where F: Future + Unpin, { CatchUnwindFuture { future: Mutex::new(future), } } impl Future for CatchUnwindFuture where F: Future + Unpin, { type Output = std::thread::Result; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let future = &self.future; let waker = cx.waker().clone(); let res = std::panic::catch_unwind(|| { let mut context = Context::from_waker(&waker); let mut guard = future.lock().unwrap(); Pin::new(&mut *guard).poll(&mut context) }); match res { Ok(poll) => poll.map(Ok), Err(e) => Poll::Ready(Err(e)), } } }