1 use core::any::Any; 2 use core::pin::Pin; 3 use std::boxed::Box; 4 use std::panic::{catch_unwind, AssertUnwindSafe, UnwindSafe}; 5 6 use futures_core::future::Future; 7 use futures_core::task::{Context, Poll}; 8 use pin_project_lite::pin_project; 9 10 pin_project! { 11 /// Future for the [`catch_unwind`](super::FutureExt::catch_unwind) method. 12 #[derive(Debug)] 13 #[must_use = "futures do nothing unless you `.await` or poll them"] 14 pub struct CatchUnwind<Fut> { 15 #[pin] 16 future: Fut, 17 } 18 } 19 20 impl<Fut> CatchUnwind<Fut> 21 where 22 Fut: Future + UnwindSafe, 23 { new(future: Fut) -> Self24 pub(super) fn new(future: Fut) -> Self { 25 Self { future } 26 } 27 } 28 29 impl<Fut> Future for CatchUnwind<Fut> 30 where 31 Fut: Future + UnwindSafe, 32 { 33 type Output = Result<Fut::Output, Box<dyn Any + Send>>; 34 poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>35 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { 36 let f = self.project().future; 37 catch_unwind(AssertUnwindSafe(|| f.poll(cx)))?.map(Ok) 38 } 39 } 40