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.
This commit is contained in:
Henry de Valence 2019-10-08 13:49:12 -07:00 committed by GitHub
parent 92dc7a5ea1
commit 1266653be2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 16 deletions

View File

@ -9,6 +9,13 @@ extern crate tracing;
#[macro_use] #[macro_use]
extern crate bitflags; 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<dyn std::error::Error + Send + Sync + 'static>;
mod network; mod network;
pub use network::Network; pub use network::Network;

View File

@ -18,7 +18,7 @@ use crate::{
constants, constants,
protocol::{codec::*, internal::*, message::*, types::*}, protocol::{codec::*, internal::*, message::*, types::*},
timestamp_collector::{PeerLastSeen, TimestampCollector}, timestamp_collector::{PeerLastSeen, TimestampCollector},
Network, BoxedStdError, Network,
}; };
use super::{ use super::{
@ -37,7 +37,7 @@ impl<S> PeerConnector<S>
where where
S: Service<Request, Response = Response> + Clone + Send + 'static, S: Service<Request, Response = Response> + Clone + Send + 'static,
S::Future: Send, S::Future: Send,
//S::Error: Into<Error>, S::Error: Into<BoxedStdError>,
{ {
/// XXX replace with a builder /// XXX replace with a builder
pub fn new(network: Network, internal_service: S, collector: &TimestampCollector) -> Self { pub fn new(network: Network, internal_service: S, collector: &TimestampCollector) -> Self {
@ -54,8 +54,7 @@ impl<S> Service<SocketAddr> for PeerConnector<S>
where where
S: Service<Request, Response = Response> + Clone + Send + 'static, S: Service<Request, Response = Response> + Clone + Send + 'static,
S::Future: Send, S::Future: Send,
S::Error: Send, S::Error: Send + Into<BoxedStdError>,
//S::Error: Into<Error>,
{ {
type Response = PeerClient; type Response = PeerClient;
type Error = Error; type Error = Error;

View File

@ -8,9 +8,12 @@ use futures::{
use tokio::prelude::*; use tokio::prelude::*;
use tower::Service; use tower::Service;
use crate::protocol::{ use crate::{
protocol::{
internal::{Request, Response}, internal::{Request, Response},
message::Message, message::Message,
},
BoxedStdError,
}; };
use super::{client::ClientRequest, PeerError}; use super::{client::ClientRequest, PeerError};
@ -51,8 +54,7 @@ pub struct PeerServer<S, Tx> {
impl<S, Tx> PeerServer<S, Tx> impl<S, Tx> PeerServer<S, Tx>
where where
S: Service<Request, Response = Response>, S: Service<Request, Response = Response>,
S::Error: Send, S::Error: Into<BoxedStdError>,
//S::Error: Into<Error>,
Tx: Sink<Message> + Unpin, Tx: Sink<Message> + Unpin,
Tx::Error: Into<Error>, Tx::Error: Into<Error>,
{ {
@ -310,14 +312,21 @@ where
async fn drive_peer_request(&mut self, req: Request) { async fn drive_peer_request(&mut self, req: Request) {
trace!(?req); trace!(?req);
use tower::ServiceExt; use tower::ServiceExt;
// XXX Drop the errors on the floor for now so that if let Err(e) = self
// we can ignore error type alignment .svc
match self.svc.ready().await { .ready()
Err(_) => self.fail_with(format_err!("svc err").into()), .await
Ok(()) => {} .map_err(|e| Error::from_boxed_compat(e.into()))
{
self.fail_with(e.into());
} }
match self.svc.call(req).await { match self
Err(_) => self.fail_with(format_err!("svc err").into()), .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::Ok) => { /* generic success, do nothing */ }
Ok(Response::Peers(addrs)) => { Ok(Response::Peers(addrs)) => {
if let Err(e) = self.peer_tx.send(Message::Addr(addrs)).await { if let Err(e) = self.peer_tx.send(Message::Addr(addrs)).await {