iota_sdk_graphql_client/
error.rs1use std::num::{ParseIntError, TryFromIntError};
6
7use cynic::GraphQlError;
8use iota_types::{AddressParseError, DigestParseError, TypeParseError};
9
10type BoxError = Box<dyn std::error::Error + Send + Sync + 'static>;
11
12pub type Result<T, E = Error> = std::result::Result<T, E>;
13
14#[derive(Debug)]
17pub struct Error {
18 inner: Box<InnerError>,
19}
20
21#[derive(Debug)]
25struct InnerError {
26 kind: Kind,
28 query_errors: Option<Vec<GraphQlError>>,
30 source: Option<BoxError>,
32}
33
34#[derive(Debug, Copy, Clone)]
35#[non_exhaustive]
36pub enum Kind {
37 Deserialization,
38 Parse,
39 Query,
40 Missing,
41 Other,
42}
43
44impl std::error::Error for Error {
45 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
46 self.inner.source.as_deref().map(|e| e as _)
47 }
48}
49
50impl Error {
51 pub fn graphql_errors(&self) -> Option<&[GraphQlError]> {
53 self.inner.query_errors.as_deref()
54 }
55
56 pub fn from_error<E: Into<BoxError>>(kind: Kind, error: E) -> Self {
58 Self {
59 inner: Box::new(InnerError {
60 kind,
61 source: Some(error.into()),
62 query_errors: None,
63 }),
64 }
65 }
66
67 pub fn from_message(kind: Kind, message: String) -> Self {
69 Self {
70 inner: Box::new(InnerError {
71 kind,
72 source: Some(message.into()),
73 query_errors: None,
74 }),
75 }
76 }
77
78 pub fn empty_response_error() -> Self {
81 Self {
82 inner: Box::new(InnerError {
83 kind: Kind::Query,
84 source: Some("Expected a non-empty response data from query".into()),
85 query_errors: None,
86 }),
87 }
88 }
89
90 pub fn graphql_error(errors: Vec<GraphQlError>) -> Self {
92 Self {
93 inner: Box::new(InnerError {
94 kind: Kind::Query,
95 source: None,
96 query_errors: Some(errors),
97 }),
98 }
99 }
100}
101
102impl std::fmt::Display for Kind {
103 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
104 match self {
105 Kind::Deserialization => write!(f, "Deserialization error:"),
106 Kind::Parse => write!(f, "Parse error:"),
107 Kind::Query => write!(f, "Query error:"),
108 Kind::Missing => write!(f, "Missing:"),
109 Kind::Other => write!(f, "Error:"),
110 }
111 }
112}
113
114impl std::fmt::Display for Error {
115 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
116 write!(f, "{}", self.inner.kind)?;
117
118 if let Some(source) = &self.inner.source {
119 write!(f, " {source}")?;
120 }
121
122 if let Some(errors) = &self.inner.query_errors {
123 write!(
124 f,
125 " [{}]",
126 errors
127 .iter()
128 .map(|e| e.to_string())
129 .collect::<Vec<_>>()
130 .join(", ")
131 )?;
132 }
133 Ok(())
134 }
135}
136
137impl From<bcs::Error> for Error {
138 fn from(error: bcs::Error) -> Self {
139 Self::from_error(Kind::Deserialization, error)
140 }
141}
142
143impl From<reqwest::Error> for Error {
144 fn from(error: reqwest::Error) -> Self {
145 Self::from_error(Kind::Other, error)
146 }
147}
148
149impl From<url::ParseError> for Error {
150 fn from(error: url::ParseError) -> Self {
151 Self::from_error(Kind::Parse, error)
152 }
153}
154
155impl From<ParseIntError> for Error {
156 fn from(error: ParseIntError) -> Self {
157 Self::from_error(Kind::Parse, error)
158 }
159}
160
161impl From<AddressParseError> for Error {
162 fn from(error: AddressParseError) -> Self {
163 Self::from_error(Kind::Parse, error)
164 }
165}
166
167impl From<base64ct::Error> for Error {
168 fn from(error: base64ct::Error) -> Self {
169 Self::from_error(Kind::Parse, error)
170 }
171}
172
173impl From<chrono::ParseError> for Error {
174 fn from(error: chrono::ParseError) -> Self {
175 Self::from_error(Kind::Parse, error)
176 }
177}
178
179impl From<DigestParseError> for Error {
180 fn from(error: DigestParseError) -> Self {
181 Self::from_error(Kind::Parse, error)
182 }
183}
184
185impl From<TryFromIntError> for Error {
186 fn from(error: TryFromIntError) -> Self {
187 Self::from_error(Kind::Parse, error)
188 }
189}
190
191impl From<TypeParseError> for Error {
192 fn from(error: TypeParseError) -> Self {
193 Self::from_error(Kind::Parse, error)
194 }
195}