1use std::{
2 error::Error as StdError,
3 marker::PhantomData,
4 pin::Pin,
5 task::{Context, Poll},
6 time::Duration,
7};
8use thiserror::Error;
9use tower_service::Service;
10
11pub type BoxDynError = Box<dyn StdError + 'static + Send + Sync>;
13#[derive(Error, Debug)]
16#[error("AbortError: {source}")]
17pub struct AbortError {
18 #[source]
19 source: BoxDynError,
20}
21impl AbortError {
22 pub fn new<E: Into<BoxDynError>>(err: E) -> Self {
24 Self { source: err.into() }
25 }
26}
27
28#[derive(Error, Debug)]
31#[error("RetryError: {source}")]
32pub struct RetryAfterError {
33 #[source]
34 source: BoxDynError,
35 duration: Duration,
36}
37
38impl RetryAfterError {
39 pub fn new<E: Into<BoxDynError>>(err: E, duration: Duration) -> Self {
41 Self {
42 source: err.into(),
43 duration,
44 }
45 }
46
47 #[must_use]
49 pub fn get_duration(&self) -> Duration {
50 self.duration
51 }
52}
53
54#[derive(Error, Debug)]
56#[error("DeferredError: {source}")]
57pub struct DeferredError {
58 #[source]
59 source: BoxDynError,
60}
61
62impl DeferredError {
63 pub fn new<E: Into<BoxDynError>>(source: E) -> Self {
65 Self {
66 source: source.into(),
67 }
68 }
69}
70
71#[non_exhaustive]
73#[derive(Error, Debug)]
74pub enum WorkerError {
75 #[error("Failed to poll backend: {0}")]
77 BackendError(BoxDynError),
78 #[error("Failed to handle the new state: {0}")]
80 StateError(#[from] WorkerStateError),
81 #[error("Worker panicked: {0}")]
83 PanicError(String),
84 #[error("IO error: {0}")]
86 IoError(#[from] std::io::Error),
87}
88
89#[derive(Error, Debug)]
91#[non_exhaustive]
92pub enum WorkerStateError {
93 #[error("Worker not started, did you forget to call worker.start()")]
95 NotStarted,
96 #[error("Worker already started")]
98 AlreadyStarted,
99 #[error("Worker is not running")]
101 NotRunning,
102 #[error("Worker is not paused")]
104 NotPaused,
105 #[error("Worker is shutting down")]
107 ShuttingDown,
108 #[error("Worker provided with invalid state {0}")]
110 InvalidState(String),
111}
112
113#[derive(Clone, Debug)]
118pub struct ErrorHandlingLayer {
119 _p: PhantomData<()>,
120}
121
122impl ErrorHandlingLayer {
123 #[must_use]
125 pub fn new() -> Self {
126 Self { _p: PhantomData }
127 }
128}
129
130impl Default for ErrorHandlingLayer {
131 fn default() -> Self {
132 Self::new()
133 }
134}
135
136impl<S> tower_layer::Layer<S> for ErrorHandlingLayer {
137 type Service = ErrorHandlingService<S>;
138
139 fn layer(&self, service: S) -> Self::Service {
140 ErrorHandlingService { service }
141 }
142}
143
144#[derive(Clone, Debug)]
146pub struct ErrorHandlingService<S> {
147 service: S,
148}
149
150impl<S, Request> Service<Request> for ErrorHandlingService<S>
151where
152 S: Service<Request>,
153 S::Error: std::error::Error + Send + Sync + 'static,
154 S::Future: Send + 'static,
155{
156 type Response = S::Response;
157 type Error = BoxDynError;
158 type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
159
160 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
161 self.service.poll_ready(cx).map_err(|e| {
162 let boxed_error: BoxDynError = e.into();
163 boxed_error
164 })
165 }
166
167 fn call(&mut self, req: Request) -> Self::Future {
168 let fut = self.service.call(req);
169
170 Box::pin(async move {
171 fut.await.map_err(|e| {
172 let boxed_error: BoxDynError = e.into();
173 boxed_error
174 })
175 })
176 }
177}