diff --git a/packages/rs-dapi-client/src/transport.rs b/packages/rs-dapi-client/src/transport.rs index 600189fc2f..8a9bc8a7b7 100644 --- a/packages/rs-dapi-client/src/transport.rs +++ b/packages/rs-dapi-client/src/transport.rs @@ -48,7 +48,7 @@ pub trait TransportRequest: Clone + Send + Sync + Debug + Mockable { /// Generic way to create a transport client from provided [Uri]. pub trait TransportClient: Send + Sized { /// Error type for the specific client. - type Error: CanRetry + Send + Debug + Mockable; + type Error: CanRetry + Send + Debug + Mockable + 'static; /// Build client using node's url. fn with_uri(uri: Uri, pool: &ConnectionPool) -> Result; diff --git a/packages/rs-sdk/src/error.rs b/packages/rs-sdk/src/error.rs index e55bda4742..35c72df329 100644 --- a/packages/rs-sdk/src/error.rs +++ b/packages/rs-sdk/src/error.rs @@ -1,8 +1,12 @@ //! Definitions of errors + +use std::any::Any; use std::fmt::Debug; use std::time::Duration; use dapi_grpc::mock::Mockable; +use dpp::consensus::ConsensusError; +use dpp::serialization::PlatformDeserializable; use dpp::version::PlatformVersionError; use dpp::ProtocolError; use rs_dapi_client::{CanRetry, DapiClientError}; @@ -73,8 +77,24 @@ pub enum Error { StaleNode(#[from] StaleNodeError), } -impl From> for Error { +impl From> for Error { fn from(value: DapiClientError) -> Self { + if let DapiClientError::Transport(ref t, _) = &value { + if let Some(status) = (t as &dyn Any).downcast_ref::() { + if let Some(consensus_error_value) = + status.metadata().get_bin("drive-error-data-bin") + { + return ConsensusError::deserialize_from_bytes( + consensus_error_value.as_encoded_bytes(), + ) + .map(|consensus_error| { + Error::Protocol(ProtocolError::ConsensusError(Box::new(consensus_error))) + }) + .unwrap_or_else(Error::Protocol); + } + } + } + Self::DapiClientError(format!("{:?}", value)) } }