hreq_h2/
error.rs

1use crate::codec::{SendError, UserError};
2use crate::proto;
3
4use std::{error, fmt, io};
5
6pub use crate::frame::Reason;
7
8/// Represents HTTP/2.0 operation errors.
9///
10/// `Error` covers error cases raised by protocol errors caused by the
11/// peer, I/O (transport) errors, and errors caused by the user of the library.
12///
13/// If the error was caused by the remote peer, then it will contain a
14/// [`Reason`] which can be obtained with the [`reason`] function.
15///
16/// [`Reason`]: struct.Reason.html
17/// [`reason`]: #method.reason
18#[derive(Debug)]
19pub struct Error {
20    kind: Kind,
21}
22
23#[derive(Debug)]
24enum Kind {
25    /// An error caused by an action taken by the remote peer.
26    ///
27    /// This is either an error received by the peer or caused by an invalid
28    /// action taken by the peer (i.e. a protocol error).
29    Proto(Reason),
30
31    /// An error resulting from an invalid action taken by the user of this
32    /// library.
33    User(UserError),
34
35    /// An `io::Error` occurred while trying to read or write.
36    Io(io::Error),
37}
38
39// ===== impl Error =====
40
41impl Error {
42    /// If the error was caused by the remote peer, the error reason.
43    ///
44    /// This is either an error received by the peer or caused by an invalid
45    /// action taken by the peer (i.e. a protocol error).
46    pub fn reason(&self) -> Option<Reason> {
47        match self.kind {
48            Kind::Proto(reason) => Some(reason),
49            _ => None,
50        }
51    }
52
53    /// Returns the true if the error is an io::Error
54    pub fn is_io(&self) -> bool {
55        match self.kind {
56            Kind::Io(_) => true,
57            _ => false,
58        }
59    }
60
61    /// Returns the error if the error is an io::Error
62    pub fn get_io(&self) -> Option<&io::Error> {
63        match self.kind {
64            Kind::Io(ref e) => Some(e),
65            _ => None,
66        }
67    }
68
69    /// Returns the error if the error is an io::Error
70    pub fn into_io(self) -> Option<io::Error> {
71        match self.kind {
72            Kind::Io(e) => Some(e),
73            _ => None,
74        }
75    }
76
77    pub(crate) fn from_io(err: io::Error) -> Self {
78        Error {
79            kind: Kind::Io(err),
80        }
81    }
82}
83
84impl From<proto::Error> for Error {
85    fn from(src: proto::Error) -> Error {
86        use crate::proto::Error::*;
87
88        Error {
89            kind: match src {
90                Proto(reason) => Kind::Proto(reason),
91                Io(e) => Kind::Io(e),
92            },
93        }
94    }
95}
96
97impl From<Reason> for Error {
98    fn from(src: Reason) -> Error {
99        Error {
100            kind: Kind::Proto(src),
101        }
102    }
103}
104
105impl From<SendError> for Error {
106    fn from(src: SendError) -> Error {
107        match src {
108            SendError::User(e) => e.into(),
109            SendError::Connection(reason) => reason.into(),
110            SendError::Io(e) => Error::from_io(e),
111        }
112    }
113}
114
115impl From<UserError> for Error {
116    fn from(src: UserError) -> Error {
117        Error {
118            kind: Kind::User(src),
119        }
120    }
121}
122
123impl fmt::Display for Error {
124    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
125        use self::Kind::*;
126
127        match self.kind {
128            Proto(ref reason) => write!(fmt, "protocol error: {}", reason),
129            User(ref e) => write!(fmt, "user error: {}", e),
130            Io(ref e) => fmt::Display::fmt(e, fmt),
131        }
132    }
133}
134
135impl error::Error for Error {}