Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions packages/zaino-fetch/src/jsonrpsee/connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,13 @@ pub enum RpcRequestError<MethodError> {
Transport(#[from] TransportError),

/// Error variant for errors related to the JSON-RPC method being called.
#[error("Method error: {0:?}")]
Method(MethodError),
///
/// The payload is `#[source]` for the same reason as
/// [`RpcRequestError::UnexpectedErrorResponse`]'s: the typed rejection
/// must stay reachable through `source()` chains for the serving
/// surfaces' downcast walks (zingolabs/zaino#1408).
#[error("Method error: {0}")]
Method(#[source] MethodError),

/// The provided input failed to serialize.
#[error("request input failed to serialize: {0:?}")]
Expand Down Expand Up @@ -1107,6 +1112,25 @@ mod tests {
);
}

/// `Method` carries the typed method-specific rejection, so — like
/// `UnexpectedErrorResponse` — its payload must stay reachable through
/// `source()` for the serving surfaces' downcast walks to attribute the
/// rejection (zingolabs/zaino#1408).
#[test]
fn method_exposes_method_error_via_source() {
use crate::jsonrpsee::response::SendTransactionError;

let error: RpcRequestError<SendTransactionError> =
RpcRequestError::Method(SendTransactionError::MissingInputs);

let source = std::error::Error::source(&error)
.expect("the method error must be exposed via source()");
assert!(
source.downcast_ref::<SendTransactionError>().is_some(),
"the source must downcast to the typed method error"
);
}

#[test]
fn test_resolve_address_wraps_common_function() {
// Verify the wrapper correctly converts io::Error to TransportError
Expand Down
45 changes: 42 additions & 3 deletions packages/zaino-state/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ pub enum MempoolError {

/// Unexpected status-related error.
#[error("Status error: {0:?}")]
StatusError(StatusError),
StatusError(#[source] StatusError),
}

/// Errors related to the `BlockCache`.
Expand Down Expand Up @@ -337,7 +337,7 @@ pub enum NonFinalisedStateError {

/// Unexpected status-related error.
#[error("Status error: {0:?}")]
StatusError(StatusError),
StatusError(#[source] StatusError),
}

/// These aren't the best conversions, but the NonFinalizedStateError should go away
Expand Down Expand Up @@ -427,7 +427,7 @@ pub enum FinalisedStateError {

/// Unexpected status-related error.
#[error("Status error: {0:?}")]
StatusError(StatusError),
StatusError(#[source] StatusError),

/// Error from JsonRpcConnector.
// TODO: Remove when FinalisedState replaces legacy finalised state.
Expand Down Expand Up @@ -663,6 +663,45 @@ impl From<MempoolError> for ChainIndexError {
}
}

#[cfg(test)]
mod status_error_wrappers {
use super::*;

fn status_error() -> StatusError {
StatusError {
server_status: crate::status::StatusType::CriticalError,
}
}

/// Asserts `error` exposes a [`StatusError`] via `source()`, the link the
/// serving surfaces' downcast walks need for attribution
/// (zingolabs/zaino#1408).
fn assert_status_error_reachable(error: &(dyn std::error::Error + 'static)) {
let source = error
.source()
.expect("the wrapped StatusError must be exposed via source()");
assert!(
source.downcast_ref::<StatusError>().is_some(),
"the source must downcast to the typed StatusError"
);
}

#[test]
fn mempool_error_exposes_status_error_via_source() {
assert_status_error_reachable(&MempoolError::StatusError(status_error()));
}

#[test]
fn non_finalised_state_error_exposes_status_error_via_source() {
assert_status_error_reachable(&NonFinalisedStateError::StatusError(status_error()));
}

#[test]
fn finalised_state_error_exposes_status_error_via_source() {
assert_status_error_reachable(&FinalisedStateError::StatusError(status_error()));
}
}

#[cfg(test)]
mod tonic_status_from_service_error {
use super::*;
Expand Down
Loading