Implement std::error::Error for Tower error types (#51)
I've implemented `std::error::Error` for the error types in the `tower-balance`, `tower-buffer`, `tower-in-flight-limit`, and `tower-reconnect` middleware crates. This is required upstream for runconduit/conduit#442, and also just generally seems like the right thing to do as a library.
This commit is contained in:
parent
e0ca6545bb
commit
cc99f32486
|
@ -12,6 +12,7 @@ extern crate tower_discover;
|
|||
use futures::{Future, Poll, Async};
|
||||
use ordermap::OrderMap;
|
||||
use rand::Rng;
|
||||
use std::{fmt, error};
|
||||
use std::marker::PhantomData;
|
||||
use tower::Service;
|
||||
use tower_discover::Discover;
|
||||
|
@ -312,6 +313,48 @@ impl<F: Future, E> Future for ResponseFuture<F, E> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ===== impl Error =====
|
||||
|
||||
impl<T, U> fmt::Display for Error<T, U>
|
||||
where
|
||||
T: fmt::Display,
|
||||
U: fmt::Display,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::Inner(ref why) =>
|
||||
write!(f, "inner service error: {}", why),
|
||||
Error::Balance(ref why) =>
|
||||
write!(f, "load balancing failed: {}", why),
|
||||
Error::NotReady => f.pad("not ready"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> error::Error for Error<T, U>
|
||||
where
|
||||
T: error::Error,
|
||||
U: error::Error,
|
||||
{
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
match *self {
|
||||
Error::Inner(ref why) => Some(why),
|
||||
Error::Balance(ref why) => Some(why),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
Error::Inner(_) => "inner service error",
|
||||
Error::Balance(_) => "load balancing failed",
|
||||
Error::NotReady => "not ready",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use futures::future;
|
||||
|
|
|
@ -18,6 +18,7 @@ use futures::sync::oneshot;
|
|||
use futures::sync::mpsc::{self, UnboundedSender, UnboundedReceiver};
|
||||
use tower::Service;
|
||||
|
||||
use std::{error, fmt};
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::atomic::Ordering::SeqCst;
|
||||
|
@ -222,3 +223,65 @@ where T: Service,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ===== impl Error =====
|
||||
|
||||
impl<T> fmt::Display for Error<T>
|
||||
where
|
||||
T: fmt::Display,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::Inner(ref why) =>
|
||||
write!(f, "inner service error: {}", why),
|
||||
Error::Closed =>
|
||||
write!(f, "buffer closed"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> error::Error for Error<T>
|
||||
where
|
||||
T: error::Error,
|
||||
{
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
if let Error::Inner(ref why) = *self {
|
||||
Some(why)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
Error::Inner(_) => "inner service error",
|
||||
Error::Closed => "buffer closed",
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ===== impl SpawnError =====
|
||||
|
||||
impl<T> fmt::Display for SpawnError<T>
|
||||
where
|
||||
T: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "error spawning buffer task: {:?}", self.inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> error::Error for SpawnError<T>
|
||||
where
|
||||
T: error::Error,
|
||||
{
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
Some(&self.inner)
|
||||
}
|
||||
|
||||
fn description(&self) -> &str {
|
||||
"error spawning buffer task"
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ use tower_ready_service::ReadyService;
|
|||
|
||||
use futures::{Future, Poll, Async};
|
||||
use futures::task::AtomicTask;
|
||||
use std::{error, fmt};
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::atomic::Ordering::SeqCst;
|
||||
|
@ -241,3 +242,41 @@ impl Shared {
|
|||
self.curr.fetch_sub(1, SeqCst);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ===== impl Error =====
|
||||
|
||||
impl<T> fmt::Display for Error<T>
|
||||
where
|
||||
T: fmt::Display,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::Upstream(ref why) =>
|
||||
write!(f, "upstream service error: {}", why),
|
||||
Error::NoCapacity =>
|
||||
write!(f, "in-flight limit exceeded"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> error::Error for Error<T>
|
||||
where
|
||||
T: error::Error,
|
||||
{
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
if let Error::Upstream(ref why) = *self {
|
||||
Some(why)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
Error::Upstream(_) => "upstream service error",
|
||||
Error::NoCapacity => "in-flight limit exceeded",
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ extern crate tower;
|
|||
use futures::{Future, Async, Poll};
|
||||
use tower::{Service, NewService};
|
||||
|
||||
use std::fmt;
|
||||
use std::{error, fmt};
|
||||
|
||||
pub struct Reconnect<T>
|
||||
where T: NewService,
|
||||
|
@ -161,3 +161,44 @@ impl<T: NewService> Future for ResponseFuture<T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ===== impl Error =====
|
||||
|
||||
impl<T, U> fmt::Display for Error<T, U>
|
||||
where
|
||||
T: fmt::Display,
|
||||
U: fmt::Display,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::Inner(ref why) =>
|
||||
write!(f, "inner service error: {}", why),
|
||||
Error::Connect(ref why) =>
|
||||
write!(f, "connection failed: {}", why),
|
||||
Error::NotReady => f.pad("not ready"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> error::Error for Error<T, U>
|
||||
where
|
||||
T: error::Error,
|
||||
U: error::Error,
|
||||
{
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
match *self {
|
||||
Error::Inner(ref why) => Some(why),
|
||||
Error::Connect(ref why) => Some(why),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
Error::Inner(_) => "inner service error",
|
||||
Error::Connect(_) => "connection failed",
|
||||
Error::NotReady => "not ready",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue