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