x11rb/
errors.rs

1//! This module contains the current mess that is error handling.
2
3use crate::x11_utils::X11Error;
4
5pub use x11rb_protocol::errors::{ConnectError, DisplayParsingError, IdsExhausted, ParseError};
6
7/// An error occurred  while dynamically loading libxcb.
8#[cfg(feature = "dl-libxcb")]
9#[derive(Debug, Clone)]
10pub enum LibxcbLoadError {
11    /// Could not open the library. The `OsString` is the library
12    /// file name and the string is the reason.
13    OpenLibError(std::ffi::OsString, String),
14    /// Could not get a symbol from the library. The byte vector is the
15    /// symbol name and the string is the reason.
16    GetSymbolError(Vec<u8>, String),
17}
18
19#[cfg(feature = "dl-libxcb")]
20impl std::fmt::Display for LibxcbLoadError {
21    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22        match self {
23            LibxcbLoadError::OpenLibError(lib_name, e) => {
24                write!(f, "failed to open library {:?}: {}", lib_name, e)
25            }
26            LibxcbLoadError::GetSymbolError(symbol, e) => write!(
27                f,
28                "failed to get symbol \"{}\": {}",
29                symbol.escape_ascii(),
30                e,
31            ),
32        }
33    }
34}
35
36#[cfg(feature = "dl-libxcb")]
37impl std::error::Error for LibxcbLoadError {}
38
39/// An error that occurred on an already established X11 connection
40#[derive(Debug)]
41#[non_exhaustive]
42pub enum ConnectionError {
43    /// An unknown error occurred.
44    ///
45    /// One situation were this error is used when libxcb indicates an error that does not match
46    /// any of the defined error conditions. Thus, libxcb is violating its own API (or new error
47    /// cases were defined, but are not yet handled by x11rb).
48    UnknownError,
49
50    /// An X11 extension was not supported by the server.
51    ///
52    /// This corresponds to `XCB_CONN_CLOSED_EXT_NOTSUPPORTED`.
53    UnsupportedExtension,
54
55    /// A request larger than the maximum request length was sent.
56    ///
57    /// This corresponds to `XCB_CONN_CLOSED_REQ_LEN_EXCEED`.
58    MaximumRequestLengthExceeded,
59
60    /// File descriptor passing failed.
61    ///
62    /// This corresponds to `XCB_CONN_CLOSED_FDPASSING_FAILED`.
63    FdPassingFailed,
64
65    /// Error while parsing some data, see `ParseError`.
66    ParseError(ParseError),
67
68    /// Out of memory.
69    ///
70    /// This is `XCB_CONN_CLOSED_MEM_INSUFFICIENT`.
71    InsufficientMemory,
72
73    /// An I/O error occurred on the connection.
74    IoError(std::io::Error),
75}
76
77impl std::error::Error for ConnectionError {}
78
79impl std::fmt::Display for ConnectionError {
80    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81        match self {
82            ConnectionError::UnknownError => write!(f, "Unknown connection error"),
83            ConnectionError::UnsupportedExtension => write!(f, "Unsupported extension"),
84            ConnectionError::InsufficientMemory => write!(f, "Insufficient memory"),
85            ConnectionError::MaximumRequestLengthExceeded => {
86                write!(f, "Maximum request length exceeded")
87            }
88            ConnectionError::FdPassingFailed => write!(f, "FD passing failed"),
89            ConnectionError::ParseError(err) => err.fmt(f),
90            ConnectionError::IoError(err) => err.fmt(f),
91        }
92    }
93}
94
95impl From<ParseError> for ConnectionError {
96    fn from(err: ParseError) -> Self {
97        ConnectionError::ParseError(err)
98    }
99}
100
101impl From<std::io::Error> for ConnectionError {
102    fn from(err: std::io::Error) -> Self {
103        ConnectionError::IoError(err)
104    }
105}
106
107/// An error that occurred with some request.
108#[derive(Debug)]
109pub enum ReplyError {
110    /// Some error occurred on the X11 connection.
111    ConnectionError(ConnectionError),
112    /// The X11 server sent an error in response to a request.
113    X11Error(X11Error),
114}
115
116impl std::error::Error for ReplyError {}
117
118impl std::fmt::Display for ReplyError {
119    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
120        match self {
121            ReplyError::ConnectionError(e) => write!(f, "{}", e),
122            ReplyError::X11Error(e) => write!(f, "X11 error {:?}", e),
123        }
124    }
125}
126
127impl From<ParseError> for ReplyError {
128    fn from(err: ParseError) -> Self {
129        Self::from(ConnectionError::from(err))
130    }
131}
132
133impl From<std::io::Error> for ReplyError {
134    fn from(err: std::io::Error) -> Self {
135        ConnectionError::from(err).into()
136    }
137}
138
139impl From<ConnectionError> for ReplyError {
140    fn from(err: ConnectionError) -> Self {
141        Self::ConnectionError(err)
142    }
143}
144
145impl From<X11Error> for ReplyError {
146    fn from(err: X11Error) -> Self {
147        Self::X11Error(err)
148    }
149}
150
151/// An error caused by some request or by the exhaustion of IDs.
152#[derive(Debug)]
153pub enum ReplyOrIdError {
154    /// All available IDs have been exhausted.
155    IdsExhausted,
156    /// Some error occurred on the X11 connection.
157    ConnectionError(ConnectionError),
158    /// The X11 server sent an error in response to a request.
159    X11Error(X11Error),
160}
161
162impl std::fmt::Display for ReplyOrIdError {
163    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
164        match self {
165            ReplyOrIdError::IdsExhausted => f.write_str("X11 IDs have been exhausted"),
166            ReplyOrIdError::ConnectionError(e) => write!(f, "{}", e),
167            ReplyOrIdError::X11Error(e) => write!(f, "X11 error {:?}", e),
168        }
169    }
170}
171
172impl std::error::Error for ReplyOrIdError {}
173
174impl From<ParseError> for ReplyOrIdError {
175    fn from(err: ParseError) -> Self {
176        ConnectionError::from(err).into()
177    }
178}
179
180impl From<ConnectionError> for ReplyOrIdError {
181    fn from(err: ConnectionError) -> Self {
182        ReplyOrIdError::ConnectionError(err)
183    }
184}
185
186impl From<X11Error> for ReplyOrIdError {
187    fn from(err: X11Error) -> Self {
188        ReplyOrIdError::X11Error(err)
189    }
190}
191
192impl From<ReplyError> for ReplyOrIdError {
193    fn from(err: ReplyError) -> Self {
194        match err {
195            ReplyError::ConnectionError(err) => ReplyOrIdError::ConnectionError(err),
196            ReplyError::X11Error(err) => ReplyOrIdError::X11Error(err),
197        }
198    }
199}
200
201impl From<IdsExhausted> for ReplyOrIdError {
202    fn from(_: IdsExhausted) -> Self {
203        ReplyOrIdError::IdsExhausted
204    }
205}