// This program shows error handling. It causes some X11 errors and shows where they end up. // // This program also serves as a (bad) integration test. To verify that the expected behaviour // occurs, it needs to do some extra work. In particular, all calls to .sequence_number() are not // needed for the example, but only for the test. Where needed, extra comments indicate how the // short version of each case would look. extern crate x11rb; use x11rb::connection::Connection; use x11rb::errors::ReplyError; use x11rb::protocol::xproto::ConnectionExt as _; use x11rb::protocol::Event; use x11rb::wrapper::ConnectionExt as _; const INVALID_WINDOW: u32 = 0; fn main() -> Result<(), Box> { let (conn, _) = connect(None).unwrap(); // For requests with responses, there are four possibilities: // We can just normally get the response or error to the request via reply() let res = conn.get_geometry(INVALID_WINDOW)?.reply(); assert!(res.is_err()); // We can decide that we do not care about the response and also do not care about errors via // discard_reply_and_errors() conn.get_geometry(INVALID_WINDOW)? .discard_reply_and_errors(); // Errors can show up as 'events' in wait_for_event() via reply_unchecked() let cookie = conn.get_geometry(INVALID_WINDOW)?; let seq1 = cookie.sequence_number(); let res = cookie.reply_unchecked()?; assert!(res.is_none()); // The short version of the above would be: // let res = conn.get_geomtry(INVALID_WINDOW)?.reply_unchecked()?; // Errors can show up as 'events' in wait_for_event() by just dropping the cookie let cookie = conn.get_geometry(INVALID_WINDOW)?; let seq2 = cookie.sequence_number(); drop(cookie); // The short version of the above would be: // drop(conn.get_geometry(INVALID_WINDOW)?); // For requests without responses, there are three possibilities // We can check for errors explicitly match conn.destroy_window(INVALID_WINDOW)?.check() { Err(ReplyError::X11Error(_)) => {} e => panic!("{e:?} unexpected"), } // We can silently ignore the error conn.destroy_window(INVALID_WINDOW)?.ignore_error(); // An error can be handled as an event. let cookie = conn.destroy_window(INVALID_WINDOW)?; let seq3 = cookie.sequence_number(); drop(cookie); // The short version of the above would be: // drop(conn.destroy_window(INVALID_WINDOW)?); // Synchronise with the server so that all errors are already received. conn.sync()?; // Now check if the things above really caused errors. This is the part that is supposed to // turn this example into a (bad) integration test. for &seq in &[seq1, seq2, seq3] { let (event, seq2) = conn.wait_for_event_with_sequence()?; match event { Event::Error(_) => {} event => panic!("Unexpectedly got {event:?} instead of an X11 error"), } assert_eq!(seq, seq2); } assert!(conn.poll_for_event()?.is_none()); println!("Done"); Ok(()) } include!("integration_test_util/connect.rs");