1 | //! This module contains the current mess that is error handling. |
2 | |
3 | use crate::x11_utils::X11Error; |
4 | |
5 | pub 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)] |
10 | pub 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" )] |
20 | impl 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" )] |
37 | impl std::error::Error for LibxcbLoadError {} |
38 | |
39 | /// An error that occurred on an already established X11 connection |
40 | #[derive (Debug)] |
41 | #[non_exhaustive ] |
42 | pub 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 | |
77 | impl std::error::Error for ConnectionError {} |
78 | |
79 | impl 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 | |
95 | impl From<ParseError> for ConnectionError { |
96 | fn from(err: ParseError) -> Self { |
97 | ConnectionError::ParseError(err) |
98 | } |
99 | } |
100 | |
101 | impl 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)] |
109 | pub 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 | |
116 | impl std::error::Error for ReplyError {} |
117 | |
118 | impl 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 | |
127 | impl From<ParseError> for ReplyError { |
128 | fn from(err: ParseError) -> Self { |
129 | Self::from(ConnectionError::from(err)) |
130 | } |
131 | } |
132 | |
133 | impl From<std::io::Error> for ReplyError { |
134 | fn from(err: std::io::Error) -> Self { |
135 | ConnectionError::from(err).into() |
136 | } |
137 | } |
138 | |
139 | impl From<ConnectionError> for ReplyError { |
140 | fn from(err: ConnectionError) -> Self { |
141 | Self::ConnectionError(err) |
142 | } |
143 | } |
144 | |
145 | impl 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)] |
153 | pub 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 | |
162 | impl 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 | |
172 | impl std::error::Error for ReplyOrIdError {} |
173 | |
174 | impl From<ParseError> for ReplyOrIdError { |
175 | fn from(err: ParseError) -> Self { |
176 | ConnectionError::from(err).into() |
177 | } |
178 | } |
179 | |
180 | impl From<ConnectionError> for ReplyOrIdError { |
181 | fn from(err: ConnectionError) -> Self { |
182 | ReplyOrIdError::ConnectionError(err) |
183 | } |
184 | } |
185 | |
186 | impl From<X11Error> for ReplyOrIdError { |
187 | fn from(err: X11Error) -> Self { |
188 | ReplyOrIdError::X11Error(err) |
189 | } |
190 | } |
191 | |
192 | impl 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 | |
201 | impl From<IdsExhausted> for ReplyOrIdError { |
202 | fn from(_: IdsExhausted) -> Self { |
203 | ReplyOrIdError::IdsExhausted |
204 | } |
205 | } |
206 | |