websocket_simple/
result.rs

1use std::fmt;
2use std::io;
3use std::borrow::Cow;
4use std::str::Utf8Error;
5use std::result::Result as StdResult;
6use std::error::Error as StdError;
7use std::convert::{From, Into};
8
9use httparse;
10#[cfg(feature="ssl")]
11use openssl::ssl::error::SslError;
12
13pub type Result<T> = StdResult<T, Error>;
14
15/// The type of an error, which may indicate other kinds of errors as the underlying cause.
16#[derive(Debug)]
17pub enum Kind {
18    /// Receive read size is equal zero. We will close the socket
19    CloseSingal,
20    /// Out Buff not enough. We will close the socket
21    OutNotEnough,
22    /// Indicates an internal application error.
23    /// The WebSocket will automatically attempt to send an Error (1011) close code.
24    Internal,
25    /// Indicates a state where some size limit has been exceeded, such as an inability to accept
26    /// any more new connections.
27    /// If a Connection is active, the WebSocket will automatically attempt to send
28    /// a Size (1009) close code.
29    Capacity,
30    /// Indicates a violation of the WebSocket protocol.
31    /// The WebSocket will automatically attempt to send a Protocol (1002) close code, or if
32    /// this error occurs during a handshake, an HTTP 400 reponse will be generated.
33    Protocol,
34    /// Indicates that the WebSocket received data that should be utf8 encoded but was not.
35    /// The WebSocket will automatically attempt to send a Invalid Frame Payload Data (1007) close
36    /// code.
37    Encoding(Utf8Error),
38    /// Indicates an underlying IO Error.
39    /// This kind of error will result in a WebSocket Connection disconnecting.
40    Io(io::Error),
41    /// Indicates a failure to parse an HTTP message.
42    /// This kind of error should only occur during a WebSocket Handshake, and a HTTP 500 response
43    /// will be generated.
44    Http(httparse::Error),
45    /// Indicates a failure to perform SSL encryption.
46    #[cfg(feature="ssl")]
47    Ssl(SslError),
48    /// A custom error kind for use by applications. This error kind involves extra overhead
49    /// because it will allocate the memory on the heap. The WebSocket ignores such errors by
50    /// default, simply passing them to the Connection Handler.
51    Custom(Box<StdError + Send + Sync>),
52}
53
54/// A struct indicating the kind of error that has occured and any precise details of that error.
55pub struct Error {
56    pub kind: Kind,
57    pub details: Cow<'static, str>,
58}
59
60impl Error {
61
62    pub fn new<I>(kind: Kind, details: I) -> Error
63        where I: Into<Cow<'static, str>>
64    {
65        Error {
66            kind: kind,
67            details: details.into(),
68        }
69    }
70
71    pub fn into_box(self) -> Box<StdError> {
72        match self.kind {
73            Kind::Custom(err) => err,
74            _ => Box::new(self),
75        }
76    }
77}
78
79impl fmt::Debug for Error {
80    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
81        if self.details.len() > 0 {
82            write!(f, "WS Error <{:?}>: {}", self.kind, self.details)
83        } else {
84            write!(f, "WS Error <{:?}>", self.kind)
85        }
86    }
87}
88
89impl fmt::Display for Error {
90
91    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92        if self.details.len() > 0 {
93            write!(f, "{}: {}", self.description(), self.details)
94        } else {
95            write!(f, "{}", self.description())
96        }
97    }
98}
99
100impl StdError for Error {
101
102    fn description(&self) -> &str {
103        match self.kind {
104            Kind::CloseSingal       => "Close Signal Error",
105            Kind::OutNotEnough      => "Outbuff NotEnough Error",
106            Kind::Internal          => "Internal Application Error",
107            Kind::Capacity          => "WebSocket at Capacity",
108            Kind::Protocol          => "WebSocket Protocol Error",
109            Kind::Encoding(ref err) => err.description(),
110            Kind::Io(ref err)       => err.description(),
111            Kind::Http(_)          => "Unable to parse HTTP",
112            #[cfg(feature="ssl")]
113            Kind::Ssl(ref err)      => err.description(),
114            Kind::Custom(ref err)   => err.description(),
115        }
116    }
117
118    fn cause(&self) -> Option<&StdError> {
119        match self.kind {
120            Kind::Encoding(ref err) => Some(err),
121            Kind::Io(ref err)       => Some(err),
122            #[cfg(feature="ssl")]
123            Kind::Ssl(ref err)      => Some(err),
124            Kind::Custom(ref err)   => Some(err.as_ref()),
125            _ => None,
126        }
127    }
128}
129
130impl From<io::Error> for Error {
131    fn from(err: io::Error) -> Error {
132        Error::new(Kind::Io(err), "")
133    }
134}
135
136impl From<httparse::Error> for Error {
137
138    fn from(err: httparse::Error) -> Error {
139        let details = match err {
140            httparse::Error::HeaderName => "Invalid byte in header name.",
141            httparse::Error::HeaderValue => "Invalid byte in header value.",
142            httparse::Error::NewLine => "Invalid byte in new line.",
143            httparse::Error::Status => "Invalid byte in Response status.",
144            httparse::Error::Token => "Invalid byte where token is required.",
145            httparse::Error::TooManyHeaders => "Parsed more headers than provided buffer can contain.",
146            httparse::Error::Version => "Invalid byte in HTTP version.",
147        };
148
149        Error::new(Kind::Http(err), details)
150    }
151
152}
153
154impl From<Utf8Error> for Error {
155    fn from(err: Utf8Error) -> Error {
156        Error::new(Kind::Encoding(err), "")
157    }
158}
159
160#[cfg(feature="ssl")]
161impl From<SslError> for Error {
162    fn from(err: SslError) -> Error {
163        Error::new(Kind::Ssl(err), "")
164    }
165}
166
167impl<B> From<Box<B>> for Error
168    where B: StdError + Send + Sync + 'static
169{
170    fn from(err: Box<B>) -> Error {
171        Error::new(Kind::Custom(err), "")
172    }
173}