zerokms_protocol/
error.rs1use static_assertions::assert_impl_all;
2use std::error::Error as StdError;
3use thiserror::Error;
4
5pub trait RetryableError {
6 fn can_retry(&self) -> bool;
7}
8
9type ShareableError = Box<dyn StdError + Send + Sync>;
10
11#[derive(Debug)]
12pub enum ViturRequestErrorKind {
13 PrepareRequest,
14 SendRequest,
15 NotFound,
16 FailureResponse,
17 ParseResponse,
18 Unauthorized,
19 Forbidden,
20 Other,
21}
22
23impl std::fmt::Display for ViturRequestErrorKind {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 write!(
26 f,
27 "{}",
28 match self {
29 Self::PrepareRequest => "PrepareRequest",
30 Self::SendRequest => "SendRequest",
31 Self::NotFound => "NotFound",
32 Self::FailureResponse => "FailureResponse",
33 Self::ParseResponse => "ParseResponse",
34 Self::Unauthorized => "Unauthorized",
35 Self::Forbidden => "Forbidden",
36 Self::Other => "Other",
37 }
38 )
39 }
40}
41
42#[derive(Debug, Error)]
43#[error("{kind}: {message}: {error}")]
44pub struct ViturRequestError {
45 pub kind: ViturRequestErrorKind,
46 pub message: &'static str,
47 pub error: ShareableError,
48 can_retry: bool,
49}
50
51assert_impl_all!(ViturRequestError: Send, Sync);
54
55impl ViturRequestError {
56 #[inline]
57 pub fn new(
58 kind: ViturRequestErrorKind,
59 message: &'static str,
60 error: impl StdError + 'static + Send + Sync,
61 ) -> Self {
62 Self {
63 kind,
64 message,
65 error: Box::new(error),
66 can_retry: false,
67 }
68 }
69
70 #[inline]
71 pub fn prepare(message: &'static str, error: impl StdError + 'static + Send + Sync) -> Self {
72 Self {
73 kind: ViturRequestErrorKind::PrepareRequest,
74 message,
75 error: Box::new(error),
76 can_retry: false,
77 }
78 }
79
80 #[inline]
81 pub fn parse(message: &'static str, error: impl StdError + 'static + Send + Sync) -> Self {
82 Self {
83 kind: ViturRequestErrorKind::ParseResponse,
84 message,
85 error: Box::new(error),
86 can_retry: false,
87 }
88 }
89
90 #[inline]
91 pub fn send(message: &'static str, error: impl StdError + 'static + Send + Sync) -> Self {
92 Self {
93 kind: ViturRequestErrorKind::SendRequest,
94 message,
95 error: Box::new(error),
96 can_retry: false,
97 }
98 }
99
100 #[inline]
101 pub fn not_found(message: &'static str, error: impl StdError + 'static + Send + Sync) -> Self {
102 Self {
103 kind: ViturRequestErrorKind::NotFound,
104 message,
105 error: Box::new(error),
106 can_retry: false,
107 }
108 }
109
110 #[inline]
111 pub fn response(message: &'static str, error: impl StdError + 'static + Send + Sync) -> Self {
112 Self {
113 kind: ViturRequestErrorKind::FailureResponse,
114 message,
115 error: Box::new(error),
116 can_retry: false,
117 }
118 }
119
120 #[inline]
121 pub fn forbidden(message: &'static str, error: impl StdError + 'static + Send + Sync) -> Self {
122 Self {
123 kind: ViturRequestErrorKind::Forbidden,
124 message,
125 error: Box::new(error),
126 can_retry: false,
127 }
128 }
129
130 #[inline]
131 pub fn other(message: &'static str, error: impl StdError + 'static + Send + Sync) -> Self {
132 Self {
133 kind: ViturRequestErrorKind::Other,
134 message,
135 error: Box::new(error),
136 can_retry: false,
137 }
138 }
139
140 pub fn with_retryable(mut self, can_retry: bool) -> Self {
141 self.can_retry = can_retry;
142 self
143 }
144
145 pub fn retryable(self) -> Self {
146 self.with_retryable(true)
147 }
148}
149
150impl RetryableError for ViturRequestError {
151 fn can_retry(&self) -> bool {
152 self.can_retry
153 }
154}