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