Lines Matching full:error

3 //! Error propagation for QEMU Rust code
5 //! This module contains [`Error`], the bridge between Rust errors and
6 //! [`Result`](std::result::Result)s and QEMU's C [`Error`](bindings::Error)
9 //! For FFI code, [`Error`] provides functions to simplify conversion between
10 //! the Rust ([`Result<>`](std::result::Result)) and C (`Error**`) conventions:
12 //! * [`ok_or_propagate`](crate::Error::ok_or_propagate),
13 //! [`bool_or_propagate`](crate::Error::bool_or_propagate),
14 //! [`ptr_or_propagate`](crate::Error::ptr_or_propagate) can be used to build
15 //! a C return value while also propagating an error condition
17 //! * [`err_or_else`](crate::Error::err_or_else) and
18 //! [`err_or_unit`](crate::Error::err_or_unit) can be used to build a `Result`
23 //! [`std::error::Error`] interface to let C errors participate in Rust's error
26 //! Rust code can also create use this module to create an error object that
29 //! simple error string, from an [`anyhow::Error`] to pass any other Rust error
32 //! The third case, corresponding to [`Error::with_error`], is the only one that
33 //! requires mentioning [`qemu_api::Error`](crate::Error) explicitly. Similar
35 //! `anyhow::Error` object will be concatenated with `:` as the separator.
48 pub type Result<T> = std::result::Result<T, Error>;
51 pub struct Error { struct
53 /// Appends the print string of the error to the msg if not None
54 cause: Option<anyhow::Error>, argument
59 impl std::error::Error for Error { argument
60 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { in source()
68 .or_else(|| self.cause.as_deref().map(std::error::Error::description)) in description()
73 impl Display for Error { implementation
89 impl From<String> for Error { implementation
93 Error { in from()
102 impl From<&'static str> for Error { implementation
106 Error { in from()
115 impl From<anyhow::Error> for Error { implementation
117 fn from(error: anyhow::Error) -> Self { in from()
119 Error { in from()
121 cause: Some(error), in from()
128 impl Error { implementation
129 /// Create a new error, prepending `msg` to the
132 pub fn with_error(msg: impl Into<Cow<'static, str>>, cause: impl Into<anyhow::Error>) -> Self { in with_error()
134 Error { in with_error()
142 /// Consume a result, returning `false` if it is an error and
143 /// `true` if it is successful. The error is propagated into
151 pub unsafe fn bool_or_propagate(result: Result<()>, errp: *mut *mut bindings::Error) -> bool { in bool_or_propagate()
156 /// Consume a result, returning a `NULL` pointer if it is an error and
167 /// See [`propagate`](Error::propagate) for more information.
171 errp: *mut *mut bindings::Error, in ptr_or_propagate() argument
178 /// a possible error into `errp`. This is similar to the C API
187 /// See [`propagate`](Error::propagate) for more information.
190 errp: *mut *mut bindings::Error, in ok_or_propagate() argument
208 /// * a local variable of (C) type `Error *`
212 pub unsafe fn propagate(self, errp: *mut *mut bindings::Error) { in propagate() argument
224 /// Convert a C `Error*` into a Rust `Result`, using
225 /// `Ok(())` if `c_error` is NULL. Free the `Error*`.
231 pub unsafe fn err_or_unit(c_error: *mut bindings::Error) -> Result<()> { in err_or_unit()
236 /// Convert a C `Error*` into a Rust `Result`, calling `f()` to
237 /// obtain an `Ok` value if `c_error` is NULL. Free the `Error*`.
242 /// Error`](bindings::Error); typically it was initialized with
245 c_error: *mut bindings::Error, in err_or_else() argument
257 impl FreeForeign for Error { implementation
258 type Foreign = bindings::Error;
260 unsafe fn free_foreign(p: *mut bindings::Error) { in free_foreign() argument
268 impl CloneToForeign for Error { implementation
272 let err: *mut c_void = libc::malloc(std::mem::size_of::<bindings::Error>()); in clone_to_foreign()
273 let err: &mut bindings::Error = &mut *err.cast(); in clone_to_foreign()
274 *err = bindings::Error { in clone_to_foreign()
288 impl FromForeign for Error { implementation
289 unsafe fn cloned_from_foreign(c_error: *const bindings::Error) -> Self { in cloned_from_foreign()
292 let error = &*c_error; in cloned_from_foreign() localVariable
293 let file = if error.src_len < 0 { in cloned_from_foreign()
295 CStr::from_ptr(error.src).to_str() in cloned_from_foreign()
299 &*error.src.cast::<u8>(), in cloned_from_foreign()
300 error.src_len as usize, in cloned_from_foreign()
304 Error { in cloned_from_foreign()
305 msg: FromForeign::cloned_from_foreign(error.msg), in cloned_from_foreign()
308 line: error.line as u32, in cloned_from_foreign()
325 fn error_for_test(msg: &CStr) -> OwnedPointer<Error> { in error_for_test() argument
329 let err: *mut c_void = libc::malloc(std::mem::size_of::<bindings::Error>()); in error_for_test()
330 let err: &mut bindings::Error = &mut *err.cast(); in error_for_test()
331 *err = bindings::Error { in error_for_test()
344 unsafe fn error_get_pretty<'a>(local_err: *mut bindings::Error) -> &'a CStr { in error_get_pretty()
351 use std::error::Error; in test_description()
353 assert_eq!(super::Error::from("msg").description(), "msg"); in test_description()
354 assert_eq!(super::Error::from("msg".to_owned()).description(), "msg"); in test_description()
359 assert_eq!(&*format!("{}", Error::from("msg")), "msg"); in test_display()
360 assert_eq!(&*format!("{}", Error::from("msg".to_owned())), "msg"); in test_display()
361 assert_eq!(&*format!("{}", Error::from(anyhow!("msg"))), "msg"); in test_display()
364 &*format!("{}", Error::with_error("msg", anyhow!("cause"))), in test_display()
372 let mut local_err: *mut bindings::Error = ptr::null_mut(); in test_bool_or_propagate()
374 assert!(Error::bool_or_propagate(Ok(()), &mut local_err)); in test_bool_or_propagate()
377 let my_err = Error::from("msg"); in test_bool_or_propagate()
378 assert!(!Error::bool_or_propagate(Err(my_err), &mut local_err)); in test_bool_or_propagate()
388 let mut local_err: *mut bindings::Error = ptr::null_mut(); in test_ptr_or_propagate()
390 let ret = Error::ptr_or_propagate(Ok("abc".to_owned()), &mut local_err); in test_ptr_or_propagate()
394 let my_err = Error::from("msg"); in test_ptr_or_propagate()
396 Error::ptr_or_propagate(Err::<String, _>(my_err), &mut local_err), in test_ptr_or_propagate()
408 let result = Error::err_or_unit(ptr::null_mut()); in test_err_or_unit()
412 let err = Error::err_or_unit(err.into_inner()).unwrap_err(); in test_err_or_unit()