From 1266653be2452f61dac6c284b5763b9f0b8950a8 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Tue, 8 Oct 2019 13:49:12 -0700 Subject: [PATCH] Handle error conversions properly. (#56) This adds a type alias, BoxedStdError, for a boxed std::error::Error trait object, and uses it in the where bounds for the generic service code. In the future, we may want to standardize on using std::error::Error exclusively, but we would then possibly lose out on backtrace information. --- zebra-network/src/lib.rs | 7 ++++++ zebra-network/src/peer/connector.rs | 7 +++--- zebra-network/src/peer/server.rs | 33 ++++++++++++++++++----------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/zebra-network/src/lib.rs b/zebra-network/src/lib.rs index 2607f796..8cd02440 100644 --- a/zebra-network/src/lib.rs +++ b/zebra-network/src/lib.rs @@ -9,6 +9,13 @@ extern crate tracing; #[macro_use] extern crate bitflags; +/// Type alias to make working with tower traits easier. +/// +/// Note: the 'static lifetime bound means that the *type* cannot have any +/// non-'static lifetimes, (e.g., when a type contains a borrow and is +/// parameterized by 'a), *not* that the object itself has 'static lifetime. +pub(crate) type BoxedStdError = Box; + mod network; pub use network::Network; diff --git a/zebra-network/src/peer/connector.rs b/zebra-network/src/peer/connector.rs index e61c9387..148747c4 100644 --- a/zebra-network/src/peer/connector.rs +++ b/zebra-network/src/peer/connector.rs @@ -18,7 +18,7 @@ use crate::{ constants, protocol::{codec::*, internal::*, message::*, types::*}, timestamp_collector::{PeerLastSeen, TimestampCollector}, - Network, + BoxedStdError, Network, }; use super::{ @@ -37,7 +37,7 @@ impl PeerConnector where S: Service + Clone + Send + 'static, S::Future: Send, - //S::Error: Into, + S::Error: Into, { /// XXX replace with a builder pub fn new(network: Network, internal_service: S, collector: &TimestampCollector) -> Self { @@ -54,8 +54,7 @@ impl Service for PeerConnector where S: Service + Clone + Send + 'static, S::Future: Send, - S::Error: Send, - //S::Error: Into, + S::Error: Send + Into, { type Response = PeerClient; type Error = Error; diff --git a/zebra-network/src/peer/server.rs b/zebra-network/src/peer/server.rs index ef4d4359..201c7dcc 100644 --- a/zebra-network/src/peer/server.rs +++ b/zebra-network/src/peer/server.rs @@ -8,9 +8,12 @@ use futures::{ use tokio::prelude::*; use tower::Service; -use crate::protocol::{ - internal::{Request, Response}, - message::Message, +use crate::{ + protocol::{ + internal::{Request, Response}, + message::Message, + }, + BoxedStdError, }; use super::{client::ClientRequest, PeerError}; @@ -51,8 +54,7 @@ pub struct PeerServer { impl PeerServer where S: Service, - S::Error: Send, - //S::Error: Into, + S::Error: Into, Tx: Sink + Unpin, Tx::Error: Into, { @@ -310,14 +312,21 @@ where async fn drive_peer_request(&mut self, req: Request) { trace!(?req); use tower::ServiceExt; - // XXX Drop the errors on the floor for now so that - // we can ignore error type alignment - match self.svc.ready().await { - Err(_) => self.fail_with(format_err!("svc err").into()), - Ok(()) => {} + if let Err(e) = self + .svc + .ready() + .await + .map_err(|e| Error::from_boxed_compat(e.into())) + { + self.fail_with(e.into()); } - match self.svc.call(req).await { - Err(_) => self.fail_with(format_err!("svc err").into()), + match self + .svc + .call(req) + .await + .map_err(|e| Error::from_boxed_compat(e.into())) + { + Err(e) => self.fail_with(e.into()), Ok(Response::Ok) => { /* generic success, do nothing */ } Ok(Response::Peers(addrs)) => { if let Err(e) = self.peer_tx.send(Message::Addr(addrs)).await {