feat: error response

This commit is contained in:
thesimplekid
2024-02-15 22:40:15 +00:00
parent 7de2413dc0
commit b663228cd2
7 changed files with 58 additions and 47 deletions

View File

@@ -32,6 +32,7 @@ once_cell = { version = "1.17", optional = true }
thiserror = { workspace = true }
async-trait = "0.1.74"
gloo = { version = "0.10.0", optional = true, features = ["net"] }
http = "1.0.0"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tokio = { workspace = true, features = ["rt-multi-thread", "time", "macros", "sync"] }

View File

@@ -1,6 +1,7 @@
//! Minreq http Client
use async_trait::async_trait;
use cashu::error::ErrorResponse;
use cashu::nuts::{
BlindedMessage, CurrencyUnit, Id, KeySet, KeysResponse, KeysetResponse, MeltBolt11Request,
MeltBolt11Response, MeltQuoteBolt11Request, MeltQuoteBolt11Response, MintBolt11Request,
@@ -53,7 +54,7 @@ impl Client for HttpClient {
match response {
Ok(res) => Ok(res),
Err(_) => Err(Error::from_json(&res.to_string())?),
Err(_) => Err(ErrorResponse::from_json(&res.to_string())?.into()),
}
}
@@ -77,7 +78,7 @@ impl Client for HttpClient {
Ok(res) => Ok(res),
Err(_) => {
warn!("Bolt11 Mint Quote Unexpected response: {:?}", res);
Err(Error::from_json(&res.status_code.to_string())?)
Err(ErrorResponse::from_json(&res.status_code.to_string())?.into())
}
}
}
@@ -106,7 +107,7 @@ impl Client for HttpClient {
match response {
Ok(res) => Ok(res),
Err(_) => Err(Error::from_json(&res.to_string())?),
Err(_) => Err(ErrorResponse::from_json(&res.to_string())?.into()),
}
}
@@ -130,7 +131,7 @@ impl Client for HttpClient {
match response {
Ok(res) => Ok(res),
Err(_) => Err(Error::from_json(&value.to_string())?),
Err(_) => Err(ErrorResponse::from_json(&value.to_string())?.into()),
}
}
@@ -159,7 +160,7 @@ impl Client for HttpClient {
match response {
Ok(res) => Ok(res),
Err(_) => Err(Error::from_json(&value.to_string())?),
Err(_) => Err(ErrorResponse::from_json(&value.to_string())?.into()),
}
}
@@ -204,7 +205,7 @@ impl Client for HttpClient {
match response {
Ok(res) => Ok(res),
Err(_) => Err(Error::from_json(&res.to_string())?),
Err(_) => Err(ErrorResponse::from_json(&res.to_string())?.into()),
}
}
@@ -218,7 +219,7 @@ impl Client for HttpClient {
match response {
Ok(res) => Ok(res),
Err(_) => Err(Error::from_json(&res.to_string())?),
Err(_) => Err(ErrorResponse::from_json(&res.to_string())?.into()),
}
}
}

View File

@@ -1,6 +1,7 @@
//! Client to connet to mint
use async_trait::async_trait;
use cashu::error::ErrorResponse;
#[cfg(feature = "nut07")]
use cashu::nuts::CheckStateResponse;
use cashu::nuts::{
@@ -10,8 +11,7 @@ use cashu::nuts::{
};
#[cfg(feature = "nut07")]
use cashu::secret::Secret;
use cashu::{utils, Amount};
use serde::{Deserialize, Serialize};
use cashu::Amount;
use thiserror::Error;
use url::Url;
@@ -44,44 +44,19 @@ pub enum Error {
#[cfg(feature = "gloo")]
#[error("`{0}`")]
Gloo(String),
#[error("Unknown Error response")]
UnknownErrorResponse(cashu::error::ErrorResponse),
/// Custom Error
#[error("`{0}`")]
Custom(String),
}
impl Error {
pub fn from_json(json: &str) -> Result<Self, Error> {
if let Ok(mint_res) = serde_json::from_str::<MintErrorResponse>(json) {
let err = mint_res
.error
.as_deref()
.or(mint_res.detail.as_deref())
.unwrap_or_default();
let mint_error = match err {
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.to_owned()),
};
Ok(mint_error)
} else {
Ok(Error::Custom(json.to_string()))
}
impl From<ErrorResponse> for Error {
fn from(err: ErrorResponse) -> Error {
Self::UnknownErrorResponse(err)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct MintErrorResponse {
code: u32,
error: Option<String>,
detail: Option<String>,
}
#[async_trait(?Send)]
pub trait Client {
async fn get_mint_keys(&self, mint_url: Url) -> Result<Vec<KeySet>, Error>;
@@ -159,6 +134,7 @@ fn join_url(url: Url, paths: &[&str]) -> Result<Url, Error> {
#[cfg(test)]
mod tests {
/*
use super::*;
#[test]
@@ -181,4 +157,5 @@ mod tests {
_ => panic!("Wrong error"),
}
}
*/
}

View File

@@ -0,0 +1 @@

View File

@@ -2,6 +2,7 @@ use std::collections::HashSet;
use std::sync::Arc;
use cashu::dhke::{sign_message, verify_message};
use cashu::error::ErrorResponse;
#[cfg(feature = "nut07")]
use cashu::nuts::nut07::{ProofState, State};
use cashu::nuts::{
@@ -13,6 +14,7 @@ use cashu::nuts::{CheckStateRequest, CheckStateResponse};
use cashu::secret::Secret;
use cashu::types::{MeltQuote, MintQuote};
use cashu::Amount;
use http::StatusCode;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use tracing::{debug, error, info};
@@ -56,6 +58,22 @@ pub enum Error {
MultipleUnits,
}
impl From<Error> for ErrorResponse {
fn from(_err: Error) -> ErrorResponse {
ErrorResponse {
code: 9999,
error: None,
detail: None,
}
}
}
impl From<Error> for (StatusCode, ErrorResponse) {
fn from(err: Error) -> (StatusCode, ErrorResponse) {
(StatusCode::NOT_FOUND, err.into())
}
}
#[derive(Clone)]
pub struct Mint {
// pub pubkey: PublicKey
@@ -177,17 +195,17 @@ impl Mint {
/// Retrieve the public keys of the active keyset for distribution to
/// wallet clients
pub async fn keyset_pubkeys(&self, keyset_id: &Id) -> Result<Option<KeysResponse>, Error> {
pub async fn keyset_pubkeys(&self, keyset_id: &Id) -> Result<KeysResponse, Error> {
let keyset = match self.localstore.get_keyset(keyset_id).await? {
Some(keyset) => keyset.clone(),
None => {
return Ok(None);
return Err(Error::UnknownKeySet);
}
};
Ok(Some(KeysResponse {
Ok(KeysResponse {
keysets: vec![keyset.into()],
}))
})
}
/// Retrieve the public keys of the active keyset for distribution to

View File

@@ -144,8 +144,6 @@ mod mint {
#[cfg(test)]
mod tests {
use core::panic;
use hex::decode;
use k256::elliptic_curve::scalar::ScalarPrimitive;

View File

@@ -1,5 +1,6 @@
use std::string::FromUtf8Error;
use serde::{Deserialize, Serialize};
use thiserror::Error;
#[derive(Debug, Error)]
@@ -16,8 +17,6 @@ pub enum Error {
/// Base64 error
#[error("`{0}`")]
Base64Error(#[from] base64::DecodeError),
#[error("`{0}`")]
CustomError(String),
/// From hex error
#[error("`{0}`")]
HexError(#[from] hex::FromHexError),
@@ -35,6 +34,22 @@ pub enum Error {
InvoiceAmountUndefined,
#[error("Proof missing required field")]
MissingProofField,
/// Custom error
#[error("`{0}`")]
CustomError(String),
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ErrorResponse {
pub code: u32,
pub error: Option<String>,
pub detail: Option<String>,
}
impl ErrorResponse {
pub fn from_json(json: &str) -> Result<Self, serde_json::Error> {
serde_json::from_str(json)
}
}
#[cfg(feature = "wallet")]