futures_retry/
error_handler.rs

1use crate::RetryPolicy;
2
3/// An error handler trait.
4///
5/// Please note that this trait is implemented for any `FnMut` closure with a compatible signature,
6/// so for some simple cases you might simply use a closure instead of creating your own type and
7/// implementing this trait for it.
8///
9/// Here's an example of an error handler that counts *consecutive* error attempts.
10///
11/// ```
12/// use futures_retry::{ErrorHandler, RetryPolicy};
13/// use std::io;
14/// use std::time::Duration;
15///
16/// pub struct CustomHandler {
17///     max_attempts: usize,
18/// }
19///
20/// impl CustomHandler {
21///
22///     pub fn new(attempts: usize) -> Self {
23///         Self {
24///             max_attempts: attempts,
25///         }
26///     }
27/// }
28///
29/// impl ErrorHandler<io::Error> for CustomHandler {
30///     type OutError = io::Error;
31///
32///     fn handle(&mut self, attempt: usize, e: io::Error) -> RetryPolicy<io::Error> {
33///         if attempt == self.max_attempts {
34///             eprintln!("No attempts left");
35///             return RetryPolicy::ForwardError(e);
36///         }
37///         match e.kind() {
38///             io::ErrorKind::ConnectionRefused => RetryPolicy::WaitRetry(Duration::from_secs(1)),
39///             io::ErrorKind::TimedOut => RetryPolicy::Repeat,
40///             _ => RetryPolicy::ForwardError(e),
41///         }
42///     }
43/// }
44/// ```
45pub trait ErrorHandler<InError> {
46    /// An error that the `handle` function will produce.
47    type OutError;
48
49    /// Handles an error.
50    ///
51    /// Refer to the [`RetryPolicy`](enum.RetryPolicy.html) type to understand what this method
52    /// might return.
53    fn handle(&mut self, attempt: usize, _: InError) -> RetryPolicy<Self::OutError>;
54
55    /// This method is called on a successful execution (before returning an item) of the underlying
56    /// future/stream.
57    ///
58    /// One can use this method to reset an internal state.
59    ///
60    /// By default the method is a no-op.
61    fn ok(&mut self, _attempt: usize) {}
62}
63
64impl<InError, F, OutError> ErrorHandler<InError> for F
65where
66    F: Unpin + FnMut(InError) -> RetryPolicy<OutError>,
67{
68    type OutError = OutError;
69
70    fn handle(&mut self, _attempt: usize, e: InError) -> RetryPolicy<OutError> {
71        (self)(e)
72    }
73}