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 Other,
19}
20
21impl std::fmt::Display for ViturRequestErrorKind {
22 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23 write!(
24 f,
25 "{}",
26 match self {
27 Self::PrepareRequest => "PrepareRequest",
28 Self::SendRequest => "SendRequest",
29 Self::NotFound => "NotFound",
30 Self::FailureResponse => "FailureResponse",
31 Self::ParseResponse => "ParseResponse",
32 Self::Other => "Other",
33 }
34 )
35 }
36}
37
38#[derive(Debug, Error)]
39#[error("{kind}: {message}: {error}")]
40pub struct ViturRequestError {
41 pub kind: ViturRequestErrorKind,
42 pub message: &'static str,
43 pub error: ShareableError,
44 can_retry: bool,
45}
46
47assert_impl_all!(ViturRequestError: Send, Sync);
50
51impl ViturRequestError {
52 #[inline]
53 pub fn prepare(message: &'static str, error: impl StdError + 'static + Send + Sync) -> Self {
54 Self {
55 kind: ViturRequestErrorKind::PrepareRequest,
56 message,
57 error: Box::new(error),
58 can_retry: false,
59 }
60 }
61
62 #[inline]
63 pub fn parse(message: &'static str, error: impl StdError + 'static + Send + Sync) -> Self {
64 Self {
65 kind: ViturRequestErrorKind::ParseResponse,
66 message,
67 error: Box::new(error),
68 can_retry: false,
69 }
70 }
71
72 #[inline]
73 pub fn send(message: &'static str, error: impl StdError + 'static + Send + Sync) -> Self {
74 Self {
75 kind: ViturRequestErrorKind::SendRequest,
76 message,
77 error: Box::new(error),
78 can_retry: false,
79 }
80 }
81
82 #[inline]
83 pub fn not_found(message: &'static str, error: impl StdError + 'static + Send + Sync) -> Self {
84 Self {
85 kind: ViturRequestErrorKind::NotFound,
86 message,
87 error: Box::new(error),
88 can_retry: false,
89 }
90 }
91
92 #[inline]
93 pub fn response(message: &'static str, error: impl StdError + 'static + Send + Sync) -> Self {
94 Self {
95 kind: ViturRequestErrorKind::FailureResponse,
96 message,
97 error: Box::new(error),
98 can_retry: false,
99 }
100 }
101
102 #[inline]
103 pub fn other(message: &'static str, error: impl StdError + 'static + Send + Sync) -> Self {
104 Self {
105 kind: ViturRequestErrorKind::Other,
106 message,
107 error: Box::new(error),
108 can_retry: false,
109 }
110 }
111
112 pub fn with_retryable(mut self, can_retry: bool) -> Self {
113 self.can_retry = can_retry;
114 self
115 }
116
117 pub fn retryable(self) -> Self {
118 self.with_retryable(true)
119 }
120}
121
122impl RetryableError for ViturRequestError {
123 fn can_retry(&self) -> bool {
124 self.can_retry
125 }
126}