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:
parent
92dc7a5ea1
commit
1266653be2
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Reference in New Issue