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: &OsString, e: &String) => {
24 write!(f, "failed to open library {:?}: {}", lib_name, e)
25 }
26 LibxcbLoadError::GetSymbolError(symbol: &Vec, e: &String) => 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: &ParseError) => err.fmt(f),
90 ConnectionError::IoError(err: &Error) => 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: &ConnectionError) => write!(f, "{}", e),
122 ReplyError::X11Error(e: &X11Error) => 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(data:"X11 IDs have been exhausted"),
166 ReplyOrIdError::ConnectionError(e: &ConnectionError) => write!(f, "{}", e),
167 ReplyOrIdError::X11Error(e: &X11Error) => 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: ConnectionError) => ReplyOrIdError::ConnectionError(err),
196 ReplyError::X11Error(err: X11Error) => ReplyOrIdError::X11Error(err),
197 }
198 }
199}
200
201impl From<IdsExhausted> for ReplyOrIdError {
202 fn from(_: IdsExhausted) -> Self {
203 ReplyOrIdError::IdsExhausted
204 }
205}
206