tokio_tower/
error.rs

1use futures_core::stream::TryStream;
2use futures_sink::Sink;
3use std::{error, fmt};
4
5/// An error that occurred while servicing a request.
6pub enum Error<T, I>
7where
8    T: Sink<I> + TryStream,
9{
10    /// The underlying transport failed to send a request.
11    BrokenTransportSend(<T as Sink<I>>::Error),
12
13    /// The underlying transport failed while attempting to receive a response.
14    ///
15    /// If `None`, the transport closed without error while there were pending requests.
16    BrokenTransportRecv(Option<<T as TryStream>::Error>),
17
18    /// Attempted to issue a `call` when no more requests can be in flight.
19    ///
20    /// See [`tower_service::Service::poll_ready`] and [`Client::with_limit`].
21    TransportFull,
22
23    /// Attempted to issue a `call`, but the underlying transport has been closed.
24    ClientDropped,
25
26    /// The server sent a response that the client was not expecting.
27    Desynchronized,
28}
29
30impl<T, I> fmt::Display for Error<T, I>
31where
32    T: Sink<I> + TryStream,
33    <T as Sink<I>>::Error: fmt::Display,
34    <T as TryStream>::Error: fmt::Display,
35{
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        match *self {
38            Error::BrokenTransportSend(_) => f.pad("underlying transport failed to send a request"),
39            Error::BrokenTransportRecv(Some(_)) => {
40                f.pad("underlying transport failed while attempting to receive a response")
41            }
42            Error::BrokenTransportRecv(None) => f.pad("transport closed with in-flight requests"),
43            Error::TransportFull => f.pad("no more in-flight requests allowed"),
44            Error::ClientDropped => f.pad("Client was dropped"),
45            Error::Desynchronized => f.pad("server sent a response the client did not expect"),
46        }
47    }
48}
49
50impl<T, I> fmt::Debug for Error<T, I>
51where
52    T: Sink<I> + TryStream,
53    <T as Sink<I>>::Error: fmt::Debug,
54    <T as TryStream>::Error: fmt::Debug,
55{
56    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57        match *self {
58            Error::BrokenTransportSend(ref se) => write!(f, "BrokenTransportSend({:?})", se),
59            Error::BrokenTransportRecv(Some(ref se)) => write!(f, "BrokenTransportRecv({:?})", se),
60            Error::BrokenTransportRecv(None) => f.pad("BrokenTransportRecv"),
61            Error::TransportFull => f.pad("TransportFull"),
62            Error::ClientDropped => f.pad("ClientDropped"),
63            Error::Desynchronized => f.pad("Desynchronized"),
64        }
65    }
66}
67
68impl<T, I> error::Error for Error<T, I>
69where
70    T: Sink<I> + TryStream,
71    <T as Sink<I>>::Error: error::Error + 'static,
72    <T as TryStream>::Error: error::Error + 'static,
73{
74    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
75        match *self {
76            Error::BrokenTransportSend(ref se) => Some(se),
77            Error::BrokenTransportRecv(Some(ref se)) => Some(se),
78            _ => None,
79        }
80    }
81}
82
83impl<T, I> Error<T, I>
84where
85    T: Sink<I> + TryStream,
86{
87    pub(crate) fn from_sink_error(e: <T as Sink<I>>::Error) -> Self {
88        Error::BrokenTransportSend(e)
89    }
90
91    pub(crate) fn from_stream_error(e: <T as TryStream>::Error) -> Self {
92        Error::BrokenTransportRecv(Some(e))
93    }
94}