breez_sdk_spark/
error.rs

1use crate::{
2    Fee,
3    lnurl::{LnurlServerError, ReqwestLnurlServerClientError},
4    persist::{self},
5};
6use bitcoin::consensus::encode::FromHexError;
7use breez_sdk_common::error::ServiceConnectivityError;
8use serde::{Deserialize, Serialize};
9use spark_wallet::SparkWalletError;
10use std::{convert::Infallible, num::TryFromIntError};
11use thiserror::Error;
12use tracing_subscriber::util::TryInitError;
13use web_time::SystemTimeError;
14
15/// Error type for the `BreezSdk`
16#[derive(Debug, Error, Clone)]
17#[cfg_attr(feature = "uniffi", derive(uniffi::Error))]
18pub enum SdkError {
19    #[error("SparkSdkError: {0}")]
20    SparkError(String),
21
22    #[error("Invalid UUID: {0}")]
23    InvalidUuid(String),
24
25    /// Invalid input error
26    #[error("Invalid input: {0}")]
27    InvalidInput(String),
28
29    /// Network error
30    #[error("Network error: {0}")]
31    NetworkError(String),
32
33    /// Storage error
34    #[error("Storage error: {0}")]
35    StorageError(String),
36
37    #[error("Chain service error: {0}")]
38    ChainServiceError(String),
39
40    #[error(
41        "Deposit claim fee exceeds for utxo: {tx}:{vout} with max fee: {max_fee:?} and actual fee: {actual_fee} sats"
42    )]
43    DepositClaimFeeExceeded {
44        tx: String,
45        vout: u32,
46        max_fee: Option<Fee>,
47        actual_fee: u64,
48    },
49
50    #[error("Missing utxo: {tx}:{vout}")]
51    MissingUtxo { tx: String, vout: u32 },
52
53    #[error("Lnurl error: {0}")]
54    LnurlError(String),
55
56    #[error("Error: {0}")]
57    Generic(String),
58}
59
60impl From<crate::chain::ChainServiceError> for SdkError {
61    fn from(e: crate::chain::ChainServiceError) -> Self {
62        SdkError::ChainServiceError(e.to_string())
63    }
64}
65
66impl From<breez_sdk_common::lnurl::error::LnurlError> for SdkError {
67    fn from(e: breez_sdk_common::lnurl::error::LnurlError) -> Self {
68        SdkError::LnurlError(e.to_string())
69    }
70}
71
72impl From<breez_sdk_common::input::ParseError> for SdkError {
73    fn from(e: breez_sdk_common::input::ParseError) -> Self {
74        SdkError::InvalidInput(e.to_string())
75    }
76}
77
78impl From<bitcoin::address::ParseError> for SdkError {
79    fn from(e: bitcoin::address::ParseError) -> Self {
80        SdkError::InvalidInput(e.to_string())
81    }
82}
83
84impl From<persist::StorageError> for SdkError {
85    fn from(e: persist::StorageError) -> Self {
86        SdkError::StorageError(e.to_string())
87    }
88}
89
90impl From<Infallible> for SdkError {
91    fn from(value: Infallible) -> Self {
92        SdkError::Generic(value.to_string())
93    }
94}
95
96impl From<String> for SdkError {
97    fn from(s: String) -> Self {
98        Self::Generic(s)
99    }
100}
101
102impl From<&str> for SdkError {
103    fn from(s: &str) -> Self {
104        Self::Generic(s.to_string())
105    }
106}
107
108impl From<SystemTimeError> for SdkError {
109    fn from(e: SystemTimeError) -> Self {
110        SdkError::Generic(e.to_string())
111    }
112}
113
114impl From<TryFromIntError> for SdkError {
115    fn from(e: TryFromIntError) -> Self {
116        SdkError::Generic(e.to_string())
117    }
118}
119
120impl From<serde_json::Error> for SdkError {
121    fn from(e: serde_json::Error) -> Self {
122        SdkError::Generic(e.to_string())
123    }
124}
125
126impl From<SparkWalletError> for SdkError {
127    fn from(e: SparkWalletError) -> Self {
128        SdkError::SparkError(e.to_string())
129    }
130}
131
132impl From<FromHexError> for SdkError {
133    fn from(e: FromHexError) -> Self {
134        SdkError::Generic(e.to_string())
135    }
136}
137
138impl From<uuid::Error> for SdkError {
139    fn from(e: uuid::Error) -> Self {
140        SdkError::InvalidUuid(e.to_string())
141    }
142}
143
144impl From<ServiceConnectivityError> for SdkError {
145    fn from(value: ServiceConnectivityError) -> Self {
146        SdkError::NetworkError(value.to_string())
147    }
148}
149
150impl From<LnurlServerError> for SdkError {
151    fn from(value: LnurlServerError) -> Self {
152        match value {
153            LnurlServerError::InvalidApiKey => {
154                SdkError::InvalidInput("Invalid api key".to_string())
155            }
156            LnurlServerError::Network {
157                statuscode,
158                message,
159            } => SdkError::NetworkError(format!(
160                "network request failed with status {statuscode}: {}",
161                message.unwrap_or(String::new())
162            )),
163            LnurlServerError::RequestFailure(e) => SdkError::NetworkError(e),
164            LnurlServerError::SigningError(e) => {
165                SdkError::Generic(format!("Failed to sign message: {e}"))
166            }
167        }
168    }
169}
170
171impl From<ReqwestLnurlServerClientError> for SdkError {
172    fn from(value: ReqwestLnurlServerClientError) -> Self {
173        SdkError::Generic(value.to_string())
174    }
175}
176
177impl From<TryInitError> for SdkError {
178    fn from(_value: TryInitError) -> Self {
179        SdkError::Generic("Logging can only be initialized once".to_string())
180    }
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize, Error, PartialEq)]
184#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
185pub enum DepositClaimError {
186    #[error(
187        "Deposit claim fee exceeds for utxo: {tx}:{vout} with max fee: {max_fee:?} and actual fee: {actual_fee} sats"
188    )]
189    DepositClaimFeeExceeded {
190        tx: String,
191        vout: u32,
192        max_fee: Option<Fee>,
193        actual_fee: u64,
194    },
195
196    #[error("Missing utxo: {tx}:{vout}")]
197    MissingUtxo { tx: String, vout: u32 },
198
199    #[error("Generic error: {message}")]
200    Generic { message: String },
201}
202
203impl From<SdkError> for DepositClaimError {
204    fn from(value: SdkError) -> Self {
205        match value {
206            SdkError::DepositClaimFeeExceeded {
207                tx,
208                vout,
209                max_fee,
210                actual_fee,
211            } => DepositClaimError::DepositClaimFeeExceeded {
212                tx,
213                vout,
214                max_fee,
215                actual_fee,
216            },
217            SdkError::MissingUtxo { tx, vout } => DepositClaimError::MissingUtxo { tx, vout },
218            SdkError::Generic(e) => DepositClaimError::Generic { message: e },
219            _ => DepositClaimError::Generic {
220                message: value.to_string(),
221            },
222        }
223    }
224}