Skip to main content

tower_resilience_fallback/
error.rs

1//! Error types for the fallback service.
2
3use std::fmt;
4
5/// Error type for the fallback service.
6#[derive(Debug)]
7pub enum FallbackError<E> {
8    /// The inner service failed and no fallback was applied (predicate didn't match),
9    /// or the error was transformed via the exception strategy.
10    Inner(E),
11
12    /// The fallback service itself failed.
13    FallbackFailed(E),
14}
15
16impl<E> FallbackError<E> {
17    /// Returns `true` if this is an inner service error.
18    pub fn is_inner(&self) -> bool {
19        matches!(self, Self::Inner(_))
20    }
21
22    /// Returns `true` if the fallback itself failed.
23    pub fn is_fallback_failed(&self) -> bool {
24        matches!(self, Self::FallbackFailed(_))
25    }
26
27    /// Converts into the inner error.
28    pub fn into_inner(self) -> E {
29        match self {
30            Self::Inner(e) | Self::FallbackFailed(e) => e,
31        }
32    }
33
34    /// Returns a reference to the inner error.
35    pub fn inner(&self) -> &E {
36        match self {
37            Self::Inner(e) | Self::FallbackFailed(e) => e,
38        }
39    }
40
41    /// Maps the inner error using the provided function.
42    pub fn map<F, U>(self, f: F) -> FallbackError<U>
43    where
44        F: FnOnce(E) -> U,
45    {
46        match self {
47            Self::Inner(e) => FallbackError::Inner(f(e)),
48            Self::FallbackFailed(e) => FallbackError::FallbackFailed(f(e)),
49        }
50    }
51}
52
53impl<E: Clone> Clone for FallbackError<E> {
54    fn clone(&self) -> Self {
55        match self {
56            Self::Inner(e) => Self::Inner(e.clone()),
57            Self::FallbackFailed(e) => Self::FallbackFailed(e.clone()),
58        }
59    }
60}
61
62impl<E: fmt::Display> fmt::Display for FallbackError<E> {
63    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64        match self {
65            Self::Inner(e) => write!(f, "inner service error: {}", e),
66            Self::FallbackFailed(e) => write!(f, "fallback failed: {}", e),
67        }
68    }
69}
70
71impl<E: std::error::Error + 'static> std::error::Error for FallbackError<E> {
72    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
73        match self {
74            Self::Inner(e) | Self::FallbackFailed(e) => Some(e),
75        }
76    }
77}