octra_sqlite/client/
error.rs1use std::collections::BTreeMap;
2use std::fmt;
3
4use serde_json::Value;
5
6pub type Result<T> = std::result::Result<T, Error>;
8
9#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct Error {
12 kind: ErrorKind,
13 code: Option<String>,
14 message: String,
15 details: Option<BTreeMap<String, Value>>,
16}
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20#[non_exhaustive]
21pub enum ErrorKind {
22 Authorization,
24 Config,
26 Decode,
28 Io,
30 Protocol,
32 Receipt,
34 Rpc,
36 Timeout,
38 Transport,
40 Wallet,
42 Other,
44}
45
46impl Error {
47 pub fn new(message: impl Into<String>) -> Self {
49 Self::with_kind(ErrorKind::Other, message)
50 }
51
52 pub fn with_kind(kind: ErrorKind, message: impl Into<String>) -> Self {
54 Self {
55 kind,
56 code: None,
57 message: message.into(),
58 details: None,
59 }
60 }
61
62 pub(crate) fn with_code(
63 kind: ErrorKind,
64 code: impl Into<String>,
65 message: impl Into<String>,
66 ) -> Self {
67 Self {
68 kind,
69 code: Some(code.into()),
70 message: message.into(),
71 details: None,
72 }
73 }
74
75 pub(crate) fn with_code_and_details(
76 kind: ErrorKind,
77 code: impl Into<String>,
78 message: impl Into<String>,
79 details: impl IntoIterator<Item = (impl Into<String>, Value)>,
80 ) -> Self {
81 Self {
82 kind,
83 code: Some(code.into()),
84 message: message.into(),
85 details: Some(
86 details
87 .into_iter()
88 .map(|(key, value)| (key.into(), value))
89 .collect(),
90 ),
91 }
92 }
93
94 pub(crate) fn with_context(mut self, context: impl AsRef<str>) -> Self {
95 self.message = format!("{}; {}", self.message, context.as_ref());
96 self
97 }
98
99 pub fn kind(&self) -> ErrorKind {
101 self.kind
102 }
103
104 pub fn code(&self) -> Option<&str> {
107 self.code.as_deref()
108 }
109
110 pub fn details(&self) -> Option<&BTreeMap<String, Value>> {
113 self.details.as_ref()
114 }
115}
116
117impl fmt::Display for Error {
118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119 f.write_str(&self.message)
120 }
121}
122
123impl std::error::Error for Error {}
124
125impl From<crate::protocol::error::Error> for Error {
126 fn from(error: crate::protocol::error::Error) -> Self {
127 Self::with_kind(ErrorKind::Protocol, error.to_string())
128 }
129}
130
131impl From<base64::DecodeError> for Error {
132 fn from(error: base64::DecodeError) -> Self {
133 Self::with_kind(ErrorKind::Decode, error.to_string())
134 }
135}
136
137impl From<hex::FromHexError> for Error {
138 fn from(error: hex::FromHexError) -> Self {
139 Self::with_kind(ErrorKind::Decode, error.to_string())
140 }
141}
142
143impl From<serde_json::Error> for Error {
144 fn from(error: serde_json::Error) -> Self {
145 Self::with_kind(ErrorKind::Decode, error.to_string())
146 }
147}
148
149impl From<std::io::Error> for Error {
150 fn from(error: std::io::Error) -> Self {
151 Self::with_kind(ErrorKind::Io, error.to_string())
152 }
153}
154
155#[cfg(feature = "http")]
156impl From<ureq::Error> for Error {
157 fn from(error: ureq::Error) -> Self {
158 Self::with_kind(ErrorKind::Transport, error.to_string())
159 }
160}