zookeeper_client/
error.rs1use std::borrow::Cow;
2use std::fmt::{self, Display, Formatter};
3use std::sync::Arc;
4
5use static_assertions::assert_impl_all;
6use thiserror::Error;
7
8#[non_exhaustive]
10#[derive(Error, Clone, Debug, PartialEq, Eq)]
11pub enum Error {
12 #[error("unable to unmarshal {entity} due to {reason}")]
13 UnmarshalError { entity: &'static str, reason: &'static &'static str },
14
15 #[error("no available hosts")]
16 NoHosts,
17
18 #[error("timeout")]
19 Timeout,
20
21 #[error("unexpected error: {0}")]
22 UnexpectedError(String),
23
24 #[error("bad arguments: {0}")]
25 BadArguments(&'static &'static str),
26
27 #[error("node not exists")]
28 NoNode,
29
30 #[error("not authorized")]
31 NoAuth,
32
33 #[error("mismatch version")]
34 BadVersion,
35
36 #[error("ephemeral node can not have children")]
37 NoChildrenForEphemerals,
38
39 #[error("node already exists")]
40 NodeExists,
41
42 #[error("node has not empty children")]
43 NotEmpty,
44
45 #[error("session expired")]
46 SessionExpired,
47
48 #[error("invalid acls")]
49 InvalidAcl,
50
51 #[error("authentication failed")]
52 AuthFailed,
53
54 #[error("session moved")]
55 SessionMoved,
56
57 #[error("write request is sent to read only server")]
58 NotReadOnly,
59
60 #[error("no watcher")]
61 NoWatcher,
62
63 #[error("exceed path quota")]
64 QuotaExceeded,
65
66 #[error("request was throttled due to server heavy loading")]
67 Throttled,
68
69 #[error("server fail to marshal client request")]
70 MarshallingError,
71
72 #[error("unimplemented operation")]
73 Unimplemented,
74
75 #[error("connection to server has lost")]
76 ConnectionLoss,
77
78 #[error("ZooKeeper reconfiguration disabled")]
79 ReconfigDisabled,
80
81 #[error("unexpected error code: {0}")]
82 UnexpectedErrorCode(i32),
83
84 #[error("client has been closed")]
85 ClientClosed,
86
87 #[error("runtime condition mismatch")]
88 RuntimeInconsistent,
89
90 #[error(transparent)]
91 Custom(CustomError),
92}
93
94#[derive(Error, Clone, Debug)]
95pub struct CustomError {
96 message: Option<Arc<Cow<'static, str>>>,
97 source: Option<Arc<dyn std::error::Error + Send + Sync + 'static>>,
98}
99
100impl Display for CustomError {
101 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
102 match (self.message.as_ref(), self.source.as_ref()) {
103 (Some(message), None) => f.write_str(message),
104 (Some(message), Some(err)) => write!(f, "{message}: {err}"),
105 (None, Some(err)) => err.fmt(f),
106 _ => unreachable!("no error message or source"),
107 }
108 }
109}
110
111impl PartialEq for CustomError {
112 fn eq(&self, other: &Self) -> bool {
113 if !self.message.eq(&other.message) {
114 return false;
115 }
116 match (self.source.as_ref(), other.source.as_ref()) {
117 (Some(lhs), Some(rhs)) => Arc::ptr_eq(lhs, rhs),
118 (None, None) => true,
119 _ => false,
120 }
121 }
122}
123
124impl Eq for CustomError {}
125
126impl Error {
127 pub(crate) fn is_terminated(&self) -> bool {
128 matches!(self, Self::NoHosts | Self::SessionExpired | Self::AuthFailed | Self::ClientClosed)
129 }
130
131 pub(crate) fn has_no_data_change(&self) -> bool {
132 match self {
133 Self::NoNode
134 | Self::NoAuth
135 | Self::BadVersion
136 | Self::NoChildrenForEphemerals
137 | Self::NodeExists
138 | Self::NotEmpty
139 | Self::InvalidAcl
140 | Self::AuthFailed
141 | Self::SessionMoved
142 | Self::NotReadOnly
143 | Self::NoWatcher
144 | Self::QuotaExceeded
145 | Self::Throttled
146 | Self::MarshallingError
147 | Self::Unimplemented
148 | Self::ReconfigDisabled
149 | Self::UnexpectedErrorCode(_) => true,
150 Self::SessionExpired => true,
152 Self::ClientClosed => true,
154 _ => false,
155 }
156 }
157
158 pub(crate) fn with_message(message: impl Into<Cow<'static, str>>) -> Self {
159 Self::Custom(CustomError { message: Some(Arc::new(message.into())), source: None })
160 }
161
162 #[allow(dead_code)]
163 pub(crate) fn with_other(
164 message: impl Into<Cow<'static, str>>,
165 source: impl std::error::Error + Send + Sync + 'static,
166 ) -> Self {
167 Self::Custom(CustomError { message: Some(Arc::new(message.into())), source: Some(Arc::new(source)) })
168 }
169
170 pub(crate) fn other(source: impl std::error::Error + Send + Sync + 'static) -> Self {
171 Self::Custom(CustomError { message: None, source: Some(Arc::new(source)) })
172 }
173}
174
175assert_impl_all!(Error: Send, Sync);
176
177impl From<std::convert::Infallible> for Error {
178 fn from(_: std::convert::Infallible) -> Error {
179 unreachable!();
180 }
181}