Skip to content

Commit

Permalink
Add FutureExt::inspect_err method
Browse files Browse the repository at this point in the history
Fixes #898
  • Loading branch information
Nemo157 committed Apr 2, 2018
1 parent 93250e9 commit aa82257
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 2 deletions.
2 changes: 1 addition & 1 deletion futures-util/src/future/inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use futures_core::task;

/// Do something with the item of a future, passing it on.
///
/// This is created by the `Future::inspect` method.
/// This is created by the [`FutureExt::inspect`] method.
#[derive(Debug)]
#[must_use = "futures do nothing unless polled"]
pub struct Inspect<A, F> where A: Future {
Expand Down
41 changes: 41 additions & 0 deletions futures-util/src/future/inspect_err.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use futures_core::{Future, Poll, Async};
use futures_core::task;

/// Do something with the error of a future, passing it on.
///
/// This is created by the [`FutureExt::inspect_err`] method.
#[derive(Debug)]
#[must_use = "futures do nothing unless polled"]
pub struct InspectErr<A, F> where A: Future {
future: A,
f: Option<F>,
}

pub fn new<A, F>(future: A, f: F) -> InspectErr<A, F>
where A: Future,
F: FnOnce(&A::Error),
{
InspectErr {
future: future,
f: Some(f),
}
}

impl<A, F> Future for InspectErr<A, F>
where A: Future,
F: FnOnce(&A::Error),
{
type Item = A::Item;
type Error = A::Error;

fn poll(&mut self, cx: &mut task::Context) -> Poll<A::Item, A::Error> {
match self.future.poll(cx) {
Ok(Async::Pending) => Ok(Async::Pending),
Ok(Async::Ready(e)) => Ok(Async::Ready(e)),
Err(e) => {
(self.f.take().expect("cannot poll InspectErr twice"))(&e);
Err(e)
},
}
}
}
30 changes: 29 additions & 1 deletion futures-util/src/future/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ mod or_else;
mod select;
mod then;
mod inspect;
mod inspect_err;
mod recover;

// impl details
Expand All @@ -49,6 +50,7 @@ pub use self::or_else::OrElse;
pub use self::select::Select;
pub use self::then::Then;
pub use self::inspect::Inspect;
pub use self::inspect_err::InspectErr;
pub use self::recover::Recover;

pub use either::Either;
Expand Down Expand Up @@ -690,7 +692,7 @@ pub trait FutureExt: Future {
///
/// When using futures, you'll often chain several of them together.
/// While working on such code, you might want to check out what's happening at
/// various parts in the pipeline. To do that, insert a call to inspect().
/// various parts in the pipeline. To do that, insert a call to `inspect`.
///
/// # Examples
///
Expand All @@ -714,6 +716,32 @@ pub trait FutureExt: Future {
assert_future::<Self::Item, Self::Error, _>(inspect::new(self, f))
}

/// Do something with the error of a future, passing it on.
///
/// When using futures, you'll often chain several of them together.
/// While working on such code, you might want to check out what's happening
/// to the errors at various parts in the pipeline. To do that, insert a
/// call to `inspect_err`.
///
/// # Examples
///
/// ```
/// # extern crate futures;
/// use futures::prelude::*;
/// use futures::future;
/// use futures::executor::block_on;
///
/// let future = future::err::<u32, u32>(1);
/// let new_future = future.inspect_err(|&x| println!("about to error: {}", x));
/// assert_eq!(block_on(new_future), Err(1));
/// ```
fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where F: FnOnce(&Self::Error) -> (),
Self: Sized,
{
assert_future::<Self::Item, Self::Error, _>(inspect_err::new(self, f))
}

/// Catches unwinding panics while polling the future.
///
/// In general, panics within a future can propagate all the way out to the
Expand Down

0 comments on commit aa82257

Please sign in to comment.