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}