Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve error handling #91

Merged
merged 13 commits into from
Oct 31, 2024
2 changes: 1 addition & 1 deletion .github/workflows/unit_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,4 @@ jobs:
name: Test for no_std
with:
command: test
args: --release --no-default-features --features embassy-rt,core,wallet,models,helpers,websocket,json-rpc
args: --release --no-default-features --features embassy-rt,core,utils,wallet,models,helpers,websocket,json-rpc
39 changes: 6 additions & 33 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ hashbrown = { version = "0.14.5", features = ["serde"] }
fnv = { version = "1.0.7", default-features = false }
derive-new = { version = "0.7.0", default-features = false }
thiserror-no-std = "2.0.2"
anyhow = { version = "1.0.69", default-features = false }
embassy-sync = "0.6.0"

# networking
Expand Down Expand Up @@ -95,6 +94,7 @@ bigdecimal = { version = "0.4.5", features = ["serde-json"] }
criterion = "0.5.1"
tokio = { version = "1.0", features = ["full"] }
embedded-io-adapters = { version = "0.6.1", features = ["tokio-1"] }
anyhow = { version = "1.0.91", no-default-features = true }

[[bench]]
name = "benchmarks"
Expand All @@ -109,42 +109,15 @@ default = [
"models",
"utils",
"helpers",
"websocket",
"json-rpc",
"websocket",
]
models = [
"transaction-models",
"request-models",
"ledger-models",
"result-models",
]
transaction-models = ["core"]
request-models = []
result-models = ["request-models", "ledger-models"]
ledger-models = []
helpers = [
"account-helpers",
"ledger-helpers",
"transaction-helpers",
"wallet-helpers",
]
account-helpers = ["core", "request-models", "result-models"]
ledger-helpers = ["request-models", "result-models"]
wallet-helpers = ["wallet", "request-models", "result-models"]
transaction-helpers = [
"wallet",
"account-helpers",
"ledger-helpers",
"request-models",
"result-models",
"transaction-models",
"ledger-models",
]
models = ["core"]
helpers = ["core", "models", "wallet"]
wallet = ["core"]
json-rpc = ["request-models", "result-models", "reqwless", "embedded-nal-async"]
json-rpc = ["models", "reqwless", "embedded-io-async", "embedded-nal-async"]
websocket = [
"request-models",
"result-models",
"models",
"futures",
"embedded-io-async",
"embedded-websocket-embedded-io",
Expand Down
2 changes: 1 addition & 1 deletion benches/benchmarks.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use xrpl::core::definitions::get_field_type_name;
use xrpl::core::binarycodec::definitions::get_field_type_name;
use xrpl::utils::xrp_to_drops;

pub fn bench_xrp_to_drops(c: &mut Criterion) {
Expand Down
12 changes: 0 additions & 12 deletions src/_anyhow/mod.rs

This file was deleted.

12 changes: 6 additions & 6 deletions src/account/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use alloc::borrow::Cow;
use anyhow::Result;
use embassy_futures::block_on;

use crate::{
Expand All @@ -12,6 +11,7 @@ use crate::{
get_xrp_balance as async_get_xrp_balance,
},
clients::XRPLClient,
exceptions::XRPLHelperResult,
},
models::{ledger::objects::AccountRoot, results::account_tx::AccountTx, XRPAmount},
};
Expand All @@ -20,7 +20,7 @@ pub fn does_account_exist<C>(
address: Cow<'_, str>,
client: &C,
ledger_index: Option<Cow<'_, str>>,
) -> Result<bool>
) -> XRPLHelperResult<bool>
where
C: XRPLClient,
{
Expand All @@ -31,7 +31,7 @@ pub fn get_next_valid_seq_number<C>(
address: Cow<'_, str>,
client: &C,
ledger_index: Option<Cow<'_, str>>,
) -> Result<u32>
) -> XRPLHelperResult<u32>
where
C: XRPLClient,
{
Expand All @@ -46,7 +46,7 @@ pub fn get_xrp_balance<'a: 'b, 'b, C>(
address: Cow<'a, str>,
client: &C,
ledger_index: Option<Cow<'a, str>>,
) -> Result<XRPAmount<'b>>
) -> XRPLHelperResult<XRPAmount<'b>>
where
C: XRPLClient,
{
Expand All @@ -57,7 +57,7 @@ pub fn get_account_root<'a: 'b, 'b, C>(
address: Cow<'a, str>,
client: &C,
ledger_index: Cow<'a, str>,
) -> Result<AccountRoot<'b>>
) -> XRPLHelperResult<AccountRoot<'b>>
where
C: XRPLClient,
{
Expand All @@ -67,7 +67,7 @@ where
pub fn get_latest_transaction<'a: 'b, 'b, C>(
address: Cow<'a, str>,
client: &C,
) -> Result<AccountTx<'b>>
) -> XRPLHelperResult<AccountTx<'b>>
where
C: XRPLClient,
{
Expand Down
30 changes: 12 additions & 18 deletions src/asynch/account/mod.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
use alloc::borrow::Cow;
use anyhow::Result;

use crate::{
core::addresscodec::{is_valid_xaddress, xaddress_to_classic_address},
models::{
ledger::objects::AccountRoot,
requests::{account_info::AccountInfo, account_tx::AccountTx},
results, XRPAmount,
results::{self},
XRPAmount,
},
Err,
};

use super::clients::XRPLAsyncClient;
use super::{clients::XRPLAsyncClient, exceptions::XRPLHelperResult};

pub async fn does_account_exist<C>(
address: Cow<'_, str>,
client: &C,
ledger_index: Option<Cow<'_, str>>,
) -> Result<bool>
) -> XRPLHelperResult<bool>
where
C: XRPLAsyncClient,
{
Expand All @@ -31,7 +30,7 @@ pub async fn get_next_valid_seq_number(
address: Cow<'_, str>,
client: &impl XRPLAsyncClient,
ledger_index: Option<Cow<'_, str>>,
) -> Result<u32> {
) -> XRPLHelperResult<u32> {
let account_info =
get_account_root(address, client, ledger_index.unwrap_or("current".into())).await?;
Ok(account_info.sequence)
Expand All @@ -41,7 +40,7 @@ pub async fn get_xrp_balance<'a: 'b, 'b, C>(
address: Cow<'a, str>,
client: &C,
ledger_index: Option<Cow<'a, str>>,
) -> Result<XRPAmount<'b>>
) -> XRPLHelperResult<XRPAmount<'b>>
where
C: XRPLAsyncClient,
{
Expand All @@ -57,16 +56,13 @@ pub async fn get_account_root<'a: 'b, 'b, C>(
address: Cow<'a, str>,
client: &C,
ledger_index: Cow<'a, str>,
) -> Result<AccountRoot<'b>>
) -> XRPLHelperResult<AccountRoot<'b>>
where
C: XRPLAsyncClient,
{
let mut classic_address = address;
if is_valid_xaddress(&classic_address) {
classic_address = match xaddress_to_classic_address(&classic_address) {
Ok(addr) => addr.0.into(),
Err(e) => return Err!(e),
};
classic_address = xaddress_to_classic_address(&classic_address)?.0.into();
}
let request = AccountInfo::new(
None,
Expand All @@ -88,15 +84,12 @@ where
pub async fn get_latest_transaction<'a: 'b, 'b, C>(
mut address: Cow<'a, str>,
client: &C,
) -> Result<results::account_tx::AccountTx<'b>>
) -> XRPLHelperResult<crate::models::results::account_tx::AccountTx<'b>>
where
C: XRPLAsyncClient,
{
if is_valid_xaddress(&address) {
address = match xaddress_to_classic_address(&address) {
Ok((address, _, _)) => address.into(),
Err(e) => return Err!(e),
};
address = xaddress_to_classic_address(&address)?.0.into();
}
let account_tx = AccountTx::new(
None,
Expand All @@ -111,5 +104,6 @@ where
None,
);
let response = client.request(account_tx.into()).await?;
response.try_into_result::<results::account_tx::AccountTx<'_>>()

Ok(response.try_into_result::<results::account_tx::AccountTx<'_>>()?)
}
10 changes: 6 additions & 4 deletions src/asynch/clients/async_client.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
use super::{client::XRPLClient, CommonFields};
use super::{client::XRPLClient, exceptions::XRPLClientResult, CommonFields};
use crate::models::{
requests::{server_state::ServerState, XRPLRequest},
results::{server_state::ServerState as ServerStateResult, XRPLResponse},
};
use anyhow::Result;

#[allow(async_fn_in_trait)]
pub trait XRPLAsyncClient: XRPLClient {
async fn request<'a: 'b, 'b>(&self, request: XRPLRequest<'a>) -> Result<XRPLResponse<'b>> {
async fn request<'a: 'b, 'b>(
&self,
request: XRPLRequest<'a>,
) -> XRPLClientResult<XRPLResponse<'b>> {
self.request_impl(request).await
}

async fn get_common_fields(&self) -> Result<CommonFields<'_>> {
async fn get_common_fields(&self) -> XRPLClientResult<CommonFields<'_>> {
let server_state = self.request(ServerState::new(None).into()).await?;
let state = server_state
.try_into_result::<ServerStateResult<'_>>()?
Expand Down
8 changes: 6 additions & 2 deletions src/asynch/clients/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
requests::{Request, XRPLRequest},
results::XRPLResponse,
};
use alloc::borrow::Cow;

Check warning on line 5 in src/asynch/clients/client.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `alloc::borrow::Cow`

Check warning on line 5 in src/asynch/clients/client.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `alloc::borrow::Cow`

Check warning on line 5 in src/asynch/clients/client.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `alloc::borrow::Cow`

Check warning on line 5 in src/asynch/clients/client.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `alloc::borrow::Cow`

Check warning on line 5 in src/asynch/clients/client.rs

View workflow job for this annotation

GitHub Actions / xrpl-rust

unused import: `alloc::borrow::Cow`
use anyhow::Result;
use url::Url;

use super::exceptions::XRPLClientResult;

#[allow(async_fn_in_trait)]
pub trait XRPLClient {
async fn request_impl<'a: 'b, 'b>(&self, request: XRPLRequest<'a>) -> Result<XRPLResponse<'b>>;
async fn request_impl<'a: 'b, 'b>(
&self,
request: XRPLRequest<'a>,
) -> XRPLClientResult<XRPLResponse<'b>>;

fn get_host(&self) -> Url;

Expand Down
65 changes: 65 additions & 0 deletions src/asynch/clients/exceptions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use thiserror_no_std::Error;

#[cfg(feature = "helpers")]
use crate::asynch::wallet::exceptions::XRPLFaucetException;
use crate::{models::XRPLModelException, XRPLSerdeJsonError};

#[cfg(feature = "json-rpc")]
use super::XRPLJsonRpcException;
#[cfg(feature = "websocket")]
use super::XRPLWebSocketException;

pub type XRPLClientResult<T, E = XRPLClientException> = core::result::Result<T, E>;

#[derive(Debug, Error)]
#[non_exhaustive]
pub enum XRPLClientException {
#[error("serde_json error: {0}")]
XRPLSerdeJsonError(#[from] XRPLSerdeJsonError),
#[error("XRPL Model error: {0}")]
XRPLModelError(#[from] XRPLModelException),
#[cfg(feature = "helpers")]
#[error("XRPL Faucet error: {0}")]
XRPLFaucetError(#[from] XRPLFaucetException),
#[cfg(feature = "websocket")]
#[error("XRPL WebSocket error: {0}")]
XRPLWebSocketError(#[from] XRPLWebSocketException),
#[cfg(feature = "json-rpc")]
#[error("XRPL JSON-RPC error: {0}")]
XRPLJsonRpcError(#[from] XRPLJsonRpcException),
#[error("URL parse error: {0}")]
UrlParseError(#[from] url::ParseError),
#[cfg(feature = "std")]
#[error("I/O error: {0}")]
IoError(#[from] alloc::io::Error),
}

impl From<serde_json::Error> for XRPLClientException {
fn from(error: serde_json::Error) -> Self {
XRPLClientException::XRPLSerdeJsonError(XRPLSerdeJsonError::from(error))
}
}

#[cfg(all(not(feature = "std"), feature = "json-rpc"))]
impl From<reqwless::Error> for XRPLClientException {
fn from(error: reqwless::Error) -> Self {
XRPLClientException::XRPLJsonRpcError(XRPLJsonRpcException::ReqwlessError(error))
}
}

#[cfg(all(feature = "std", feature = "websocket"))]
impl From<tokio_tungstenite::tungstenite::Error> for XRPLClientException {
fn from(error: tokio_tungstenite::tungstenite::Error) -> Self {
XRPLClientException::XRPLWebSocketError(XRPLWebSocketException::from(error))
}
}

#[cfg(all(feature = "std", feature = "json-rpc"))]
impl From<reqwest::Error> for XRPLClientException {
fn from(error: reqwest::Error) -> Self {
XRPLClientException::XRPLJsonRpcError(XRPLJsonRpcException::ReqwestError(error))
}
}

#[cfg(feature = "std")]
impl alloc::error::Error for XRPLClientException {}
9 changes: 5 additions & 4 deletions src/asynch/clients/json_rpc/exceptions.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use thiserror_no_std::Error;

#[derive(Debug, Error)]
#[non_exhaustive]
pub enum XRPLJsonRpcException {
#[error("Reqwless error")]
ReqwlessError,
#[error("Reqwless error: {0:?}")]
ReqwlessError(#[from] reqwless::Error),
#[cfg(feature = "std")]
#[error("Request error: {0:?}")]
RequestError(reqwest::Response),
#[error("Reqwest error: {0:?}")]
ReqwestError(#[from] reqwest::Error),
}
Loading
Loading