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]
|
#[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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue