diff --git a/Cargo.toml b/Cargo.toml index 029741d0..5e5c1d7a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ getrandom = { version = "0.2", features = ["js"] } serde = { version = "1.0.160", features = ["derive"]} serde_json = "1.0.96" url = "2.3.1" +regex = "1.8.4" [dev-dependencies] tokio = {version = "1.27.0", features = ["rt", "macros"] } diff --git a/src/client.rs b/src/client.rs index 24c22c12..6085a2b1 100644 --- a/src/client.rs +++ b/src/client.rs @@ -13,12 +13,14 @@ use crate::{ CheckSpendableRequest, CheckSpendableResponse, MeltRequest, MeltResponse, MintInfo, MintRequest, PostMintResponse, Proof, RequestMintResponse, SplitRequest, SplitResponse, }, + utils, }; use serde::{Deserialize, Serialize}; #[derive(Debug)] pub enum Error { InvoiceNotPaid, + LightingWalletNotResponding(Option), /// Parse Url Error UrlParseError(url::ParseError), /// Serde Json error @@ -53,6 +55,13 @@ impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Error::InvoiceNotPaid => write!(f, "Invoice not paid"), + Error::LightingWalletNotResponding(mint) => { + write!( + f, + "Lightning Wallet not responding: {}", + mint.clone().unwrap_or("".to_string()) + ) + } Error::UrlParseError(err) => write!(f, "{}", err), Error::SerdeJsonError(err) => write!(f, "{}", err), Error::MinReqError(err) => write!(f, "{}", err), @@ -71,9 +80,13 @@ impl Error { pub fn from_json(json: &str) -> Result { let mint_res: MintErrorResponse = serde_json::from_str(json)?; - let mint_error = match mint_res.error.as_str() { - "Lightning invoice not paid yet." => Error::InvoiceNotPaid, - _ => Error::Custom(mint_res.error), + let mint_error = match mint_res.error { + error if error.starts_with("Lightning invoice not paid yet.") => Error::InvoiceNotPaid, + error if error.starts_with("Lightning wallet not responding") => { + let mint = utils::extract_url_from_error(&error); + Error::LightingWalletNotResponding(mint) + } + error => Error::Custom(error), }; Ok(mint_error) } @@ -304,6 +317,13 @@ mod tests { _ => panic!("Wrong error"), } - // assert_eq!(error, Error::InvoiceNotPaid); + let err = r#"{"code": 0, "error": "Lightning wallet not responding: Failed to connect to https://legend.lnbits.com due to: All connection attempts failed"}"#; + let error = Error::from_json(err).unwrap(); + match error { + Error::LightingWalletNotResponding(mint) => { + assert_eq!(mint, Some("https://legend.lnbits.com".to_string())); + } + _ => panic!("Wrong error"), + } } } diff --git a/src/utils.rs b/src/utils.rs index 320f21ed..ce669edd 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -3,6 +3,7 @@ use base64::{engine::general_purpose, Engine as _}; use bitcoin::Amount; use rand::prelude::*; +use regex::Regex; /// Split amount into cashu denominations (powers of 2) pub fn split_amount(amount: Amount) -> Vec { @@ -17,6 +18,14 @@ pub fn split_amount(amount: Amount) -> Vec { chunks } +pub fn extract_url_from_error(error: &str) -> Option { + let regex = Regex::new(r"https?://[^\s]+").unwrap(); + if let Some(capture) = regex.captures(error) { + return Some(capture[0].to_owned()); + } + None +} + /// Generate Secret Message pub fn generate_secret() -> String { let mut rng = rand::thread_rng();