deadpool/managed/
errors.rs

1use std::{borrow::Cow, fmt};
2
3use super::hooks::HookError;
4
5/// Possible errors returned by the [`Manager::recycle()`] method.
6///
7/// [`Manager::recycle()`]: super::Manager::recycle
8#[derive(Debug)]
9pub enum RecycleError<E> {
10    /// Recycling failed for some other reason.
11    Message(Cow<'static, str>),
12
13    /// Error caused by the backend.
14    Backend(E),
15}
16
17impl<E> RecycleError<E> {
18    /// Convenience constructor function for the `HookError::Message`
19    /// variant.
20    pub fn message(msg: impl Into<Cow<'static, str>>) -> Self {
21        Self::Message(msg.into())
22    }
23}
24
25impl<E> From<E> for RecycleError<E> {
26    fn from(e: E) -> Self {
27        Self::Backend(e)
28    }
29}
30
31impl<E: fmt::Display> fmt::Display for RecycleError<E> {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        match self {
34            Self::Message(msg) => write!(f, "Error occurred while recycling an object: {}", msg),
35            Self::Backend(e) => write!(f, "Error occurred while recycling an object: {}", e),
36        }
37    }
38}
39
40impl<E: std::error::Error + 'static> std::error::Error for RecycleError<E> {
41    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
42        match self {
43            Self::Message(_) => None,
44            Self::Backend(e) => Some(e),
45        }
46    }
47}
48
49/// Possible steps causing the timeout in an error returned by [`Pool::get()`]
50/// method.
51///
52/// [`Pool::get()`]: super::Pool::get
53#[derive(Clone, Copy, Debug)]
54pub enum TimeoutType {
55    /// Timeout happened while waiting for a slot to become available.
56    Wait,
57
58    /// Timeout happened while creating a new object.
59    Create,
60
61    /// Timeout happened while recycling an object.
62    Recycle,
63}
64
65/// Possible errors returned by [`Pool::get()`] method.
66///
67/// [`Pool::get()`]: super::Pool::get
68#[derive(Debug)]
69pub enum PoolError<E> {
70    /// Timeout happened.
71    Timeout(TimeoutType),
72
73    /// Backend reported an error.
74    Backend(E),
75
76    /// [`Pool`] has been closed.
77    ///
78    /// [`Pool`]: super::Pool
79    Closed,
80
81    /// No [`Runtime`] was specified.
82    ///
83    /// [`Runtime`]: crate::Runtime
84    NoRuntimeSpecified,
85
86    /// A `post_create` hook reported an error.
87    PostCreateHook(HookError<E>),
88}
89
90impl<E> From<E> for PoolError<E> {
91    fn from(e: E) -> Self {
92        Self::Backend(e)
93    }
94}
95
96impl<E: fmt::Display> fmt::Display for PoolError<E> {
97    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98        match self {
99            Self::Timeout(tt) => match tt {
100                TimeoutType::Wait => write!(
101                    f,
102                    "Timeout occurred while waiting for a slot to become available"
103                ),
104                TimeoutType::Create => write!(f, "Timeout occurred while creating a new object"),
105                TimeoutType::Recycle => write!(f, "Timeout occurred while recycling an object"),
106            },
107            Self::Backend(e) => write!(f, "Error occurred while creating a new object: {}", e),
108            Self::Closed => write!(f, "Pool has been closed"),
109            Self::NoRuntimeSpecified => write!(f, "No runtime specified"),
110            Self::PostCreateHook(e) => writeln!(f, "`post_create` hook failed: {}", e),
111        }
112    }
113}
114
115impl<E: std::error::Error + 'static> std::error::Error for PoolError<E> {
116    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
117        match self {
118            Self::Timeout(_) | Self::Closed | Self::NoRuntimeSpecified => None,
119            Self::Backend(e) => Some(e),
120            Self::PostCreateHook(e) => Some(e),
121        }
122    }
123}