use std::{ future::Future, panic::AssertUnwindSafe, pin::Pin, task::{Context, Poll}, }; pub(crate) struct CatchUnwindFuture { future: F, } pub(crate) fn catch_unwind(future: F) -> CatchUnwindFuture where F: Future + Unpin, { CatchUnwindFuture { 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 = &mut self.get_mut().future; let waker = cx.waker().clone(); let res = std::panic::catch_unwind(AssertUnwindSafe(|| { let mut context = Context::from_waker(&waker); Pin::new(future).poll(&mut context) })); match res { Ok(poll) => poll.map(Ok), Err(e) => Poll::Ready(Err(e)), } } }