1use std::any::Any;
2use std::fmt;
3
4#[derive(Debug)]
6pub struct DeserializeError(pub Box<dyn std::error::Error + Send + Sync>);
7
8impl fmt::Display for DeserializeError {
9 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10 write!(f, "{}", self.0)
11 }
12}
13
14impl std::error::Error for DeserializeError {
15 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
16 Some(&*self.0)
17 }
18}
19
20impl From<serde_json::Error> for DeserializeError {
21 fn from(err: serde_json::Error) -> Self {
22 DeserializeError(Box::new(err))
23 }
24}
25
26impl From<erased_serde::Error> for DeserializeError {
27 fn from(err: erased_serde::Error) -> Self {
28 DeserializeError(Box::new(err))
29 }
30}
31
32#[derive(Debug)]
34pub struct SerializeError(pub Box<dyn std::error::Error + Send + Sync>);
35
36impl fmt::Display for SerializeError {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 write!(f, "{}", self.0)
39 }
40}
41
42impl std::error::Error for SerializeError {
43 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
44 Some(&*self.0)
45 }
46}
47
48impl From<serde_json::Error> for SerializeError {
49 fn from(err: serde_json::Error) -> Self {
50 SerializeError(Box::new(err))
51 }
52}
53
54#[derive(Debug)]
60pub enum ProcedureError {
61 Deserialize(DeserializeError),
63 Serialize(SerializeError),
65 Unwind(Box<dyn Any + Send>),
67 Resolver(Box<dyn std::error::Error + Send + Sync>),
69}
70
71impl fmt::Display for ProcedureError {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 match self {
74 ProcedureError::Deserialize(e) => write!(f, "deserialization error: {e}"),
75 ProcedureError::Serialize(e) => write!(f, "serialization error: {e}"),
76 ProcedureError::Unwind(_) => write!(f, "handler panicked"),
77 ProcedureError::Resolver(e) => write!(f, "{e}"),
78 }
79 }
80}
81
82impl std::error::Error for ProcedureError {
83 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
84 match self {
85 ProcedureError::Deserialize(e) => Some(e),
86 ProcedureError::Serialize(e) => Some(e),
87 ProcedureError::Unwind(_) => None,
88 ProcedureError::Resolver(e) => Some(&**e),
89 }
90 }
91}
92
93impl From<DeserializeError> for ProcedureError {
94 fn from(err: DeserializeError) -> Self {
95 ProcedureError::Deserialize(err)
96 }
97}
98
99impl From<SerializeError> for ProcedureError {
100 fn from(err: SerializeError) -> Self {
101 ProcedureError::Serialize(err)
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use std::error::Error;
108
109 use super::*;
110
111 #[test]
112 fn deserialize_error_display() {
113 let err = DeserializeError(Box::new(std::io::Error::new(
114 std::io::ErrorKind::InvalidData,
115 "bad input",
116 )));
117 assert_eq!(err.to_string(), "bad input");
118 }
119
120 #[test]
121 fn serialize_error_display() {
122 let err = SerializeError(Box::new(std::io::Error::other("write failed")));
123 assert_eq!(err.to_string(), "write failed");
124 }
125
126 #[test]
127 fn procedure_error_deserialize_variant() {
128 let err = ProcedureError::Deserialize(DeserializeError(Box::new(std::io::Error::new(
129 std::io::ErrorKind::InvalidData,
130 "bad json",
131 ))));
132 assert!(err.to_string().contains("deserialization error"));
133 assert!(err.to_string().contains("bad json"));
134 assert!(err.source().is_some());
135 }
136
137 #[test]
138 fn procedure_error_serialize_variant() {
139 let err = ProcedureError::Serialize(SerializeError(Box::new(std::io::Error::other(
140 "encode failed",
141 ))));
142 assert!(err.to_string().contains("serialization error"));
143 assert!(err.source().is_some());
144 }
145
146 #[test]
147 fn procedure_error_unwind_variant() {
148 let err = ProcedureError::Unwind(Box::new("panic message"));
149 assert_eq!(err.to_string(), "handler panicked");
150 assert!(err.source().is_none());
151 }
152
153 #[test]
154 fn procedure_error_resolver_variant() {
155 let err = ProcedureError::Resolver(Box::new(std::io::Error::new(
156 std::io::ErrorKind::NotFound,
157 "user not found",
158 )));
159 assert_eq!(err.to_string(), "user not found");
160 assert!(err.source().is_some());
161 }
162
163 #[test]
164 fn from_deserialize_error() {
165 let de_err = DeserializeError(Box::new(std::io::Error::other("test")));
166 let proc_err: ProcedureError = de_err.into();
167 assert!(matches!(proc_err, ProcedureError::Deserialize(_)));
168 }
169
170 #[test]
171 fn from_serialize_error() {
172 let se_err = SerializeError(Box::new(std::io::Error::other("test")));
173 let proc_err: ProcedureError = se_err.into();
174 assert!(matches!(proc_err, ProcedureError::Serialize(_)));
175 }
176
177 #[test]
178 fn deserialize_error_from_serde_json() {
179 let json_err = serde_json::from_str::<String>("not json").unwrap_err();
180 let de_err: DeserializeError = json_err.into();
181 assert!(!de_err.to_string().is_empty());
182 }
183
184 #[test]
185 fn procedure_error_is_send() {
186 fn assert_send<T: Send>() {}
187 assert_send::<ProcedureError>();
188 }
189}