bsv_wallet_toolbox/
error.rs1use serde::{Deserialize, Serialize};
8use thiserror::Error;
9
10pub type WalletResult<T> = Result<T, WalletError>;
12
13#[derive(Debug, Error)]
18pub enum WalletError {
19 #[error("WERR_INTERNAL: {0}")]
21 Internal(String),
22
23 #[error("WERR_INVALID_PARAMETER: The {parameter} parameter must be {must_be}")]
25 InvalidParameter {
26 parameter: String,
28 must_be: String,
30 },
31
32 #[error("WERR_NOT_IMPLEMENTED: {0}")]
34 NotImplemented(String),
35
36 #[error("WERR_BAD_REQUEST: {0}")]
38 BadRequest(String),
39
40 #[error("WERR_UNAUTHORIZED: {0}")]
42 Unauthorized(String),
43
44 #[error("WERR_NOT_ACTIVE: {0}")]
46 NotActive(String),
47
48 #[error("WERR_INVALID_OPERATION: {0}")]
50 InvalidOperation(String),
51
52 #[error("WERR_MISSING_PARAMETER: The required {0} parameter is missing.")]
54 MissingParameter(String),
55
56 #[error("WERR_INSUFFICIENT_FUNDS: {message}")]
58 InsufficientFunds {
59 message: String,
61 total_satoshis_needed: i64,
63 more_satoshis_needed: i64,
65 },
66
67 #[error("WERR_BROADCAST_UNAVAILABLE: Unable to broadcast transaction at this time.")]
69 BroadcastUnavailable,
70
71 #[error("WERR_NETWORK_CHAIN: {0}")]
73 NetworkChain(String),
74
75 #[error("WERR_INVALID_PUBLIC_KEY: {message}")]
77 InvalidPublicKey {
78 message: String,
80 key: String,
82 },
83
84 #[error("WERR_INTERNAL: {0}")]
86 Sqlx(#[from] sqlx::Error),
87
88 #[error("WERR_INTERNAL: {0}")]
90 Io(#[from] std::io::Error),
91
92 #[error("WERR_INTERNAL: {0}")]
94 SerdeJson(#[from] serde_json::Error),
95}
96
97impl WalletError {
98 pub fn code(&self) -> &'static str {
100 match self {
101 Self::Internal(_) | Self::Sqlx(_) | Self::Io(_) | Self::SerdeJson(_) => "WERR_INTERNAL",
102 Self::InvalidParameter { .. } => "WERR_INVALID_PARAMETER",
103 Self::NotImplemented(_) => "WERR_NOT_IMPLEMENTED",
104 Self::BadRequest(_) => "WERR_BAD_REQUEST",
105 Self::Unauthorized(_) => "WERR_UNAUTHORIZED",
106 Self::NotActive(_) => "WERR_NOT_ACTIVE",
107 Self::InvalidOperation(_) => "WERR_INVALID_OPERATION",
108 Self::MissingParameter(_) => "WERR_MISSING_PARAMETER",
109 Self::InsufficientFunds { .. } => "WERR_INSUFFICIENT_FUNDS",
110 Self::BroadcastUnavailable => "WERR_BROADCAST_UNAVAILABLE",
111 Self::NetworkChain(_) => "WERR_NETWORK_CHAIN",
112 Self::InvalidPublicKey { .. } => "WERR_INVALID_PUBLIC_KEY",
113 }
114 }
115
116 pub fn to_wallet_error_object(&self) -> WalletErrorObject {
120 WalletErrorObject {
121 is_error: true,
122 name: self.code().to_string(),
123 message: self.to_string(),
124 code: None,
125 parameter: match self {
126 Self::InvalidParameter { parameter, .. } => Some(parameter.clone()),
127 Self::MissingParameter(p) => Some(p.clone()),
128 _ => None,
129 },
130 total_satoshis_needed: match self {
131 Self::InsufficientFunds {
132 total_satoshis_needed,
133 ..
134 } => Some(*total_satoshis_needed),
135 _ => None,
136 },
137 more_satoshis_needed: match self {
138 Self::InsufficientFunds {
139 more_satoshis_needed,
140 ..
141 } => Some(*more_satoshis_needed),
142 _ => None,
143 },
144 }
145 }
146}
147
148pub fn wallet_error_from_object(obj: WalletErrorObject) -> WalletError {
154 match obj.name.as_str() {
155 "WERR_INVALID_PARAMETER" => WalletError::InvalidParameter {
156 parameter: obj.parameter.unwrap_or_default(),
157 must_be: obj.message,
158 },
159 "WERR_NOT_IMPLEMENTED" => WalletError::NotImplemented(obj.message),
160 "WERR_BAD_REQUEST" => WalletError::BadRequest(obj.message),
161 "WERR_UNAUTHORIZED" => WalletError::Unauthorized(obj.message),
162 "WERR_NOT_ACTIVE" => WalletError::NotActive(obj.message),
163 "WERR_INVALID_OPERATION" => WalletError::InvalidOperation(obj.message),
164 "WERR_MISSING_PARAMETER" => {
165 WalletError::MissingParameter(obj.parameter.unwrap_or_else(|| obj.message.clone()))
166 }
167 "WERR_INSUFFICIENT_FUNDS" => WalletError::InsufficientFunds {
168 message: obj.message,
169 total_satoshis_needed: obj.total_satoshis_needed.unwrap_or(0),
170 more_satoshis_needed: obj.more_satoshis_needed.unwrap_or(0),
171 },
172 "WERR_BROADCAST_UNAVAILABLE" => WalletError::BroadcastUnavailable,
173 "WERR_NETWORK_CHAIN" => WalletError::NetworkChain(obj.message),
174 "WERR_INVALID_PUBLIC_KEY" => WalletError::InvalidPublicKey {
175 message: obj.message,
176 key: obj.parameter.unwrap_or_default(),
177 },
178 _ => WalletError::Internal(obj.message),
179 }
180}
181
182#[derive(Debug, Serialize, Deserialize)]
184#[serde(rename_all = "camelCase")]
185pub struct WalletErrorObject {
186 pub is_error: bool,
188 pub name: String,
190 pub message: String,
192 #[serde(skip_serializing_if = "Option::is_none")]
194 pub code: Option<u8>,
195 #[serde(skip_serializing_if = "Option::is_none")]
197 pub parameter: Option<String>,
198 #[serde(skip_serializing_if = "Option::is_none")]
200 pub total_satoshis_needed: Option<i64>,
201 #[serde(skip_serializing_if = "Option::is_none")]
203 pub more_satoshis_needed: Option<i64>,
204}