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]
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;
pub use network::Network;

View File

@ -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<S> PeerConnector<S>
where
S: Service<Request, Response = Response> + Clone + Send + 'static,
S::Future: Send,
//S::Error: Into<Error>,
S::Error: Into<BoxedStdError>,
{
/// XXX replace with a builder
pub fn new(network: Network, internal_service: S, collector: &TimestampCollector) -> Self {
@ -54,8 +54,7 @@ impl<S> Service<SocketAddr> for PeerConnector<S>
where
S: Service<Request, Response = Response> + Clone + Send + 'static,
S::Future: Send,
S::Error: Send,
//S::Error: Into<Error>,
S::Error: Send + Into<BoxedStdError>,
{
type Response = PeerClient;
type Error = Error;

View File

@ -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<S, Tx> {
impl<S, Tx> PeerServer<S, Tx>
where
S: Service<Request, Response = Response>,
S::Error: Send,
//S::Error: Into<Error>,
S::Error: Into<BoxedStdError>,
Tx: Sink<Message> + Unpin,
Tx::Error: Into<Error>,
{
@ -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 {