Attaching errors to events
In Rust, errors are typically communicated through the Error
trait. If you attach a property with the err
well-known property to an event, it will automatically try capture it using its Error
implementation:
#![allow(unused)] fn main() { extern crate emit; fn write_to_file(bytes: &[u8]) -> std::io::Result<()> { Err(std::io::Error::new(std::io::ErrorKind::Other, "the file is in an invalid state")) } if let Err(err) = write_to_file(b"Hello") { emit::warn!("file write failed: {err}"); } }
Event {
mdl: "emit_sample",
tpl: "file write failed: {err}",
extent: Some(
"2024-10-02T21:14:40.566303000Z",
),
props: {
"err": Custom {
kind: Other,
error: "the file is in an invalid state",
},
"lvl": warn,
},
}
Emitters may treat the err
property specially when receiving diagnostic events, such as by displaying them more prominently.
You can also use the #[as_error]
attribute on a property to capture it using its Error
implementation.
Mapping error types
Attaching errors to events requires they're either &str
, &(dyn std::error::Error + 'static)
, or impl std::error::Error
. Error types like anyhow::Error
don't satisfy these requirements so need to be mapped. Since property values are expressions, you can do this in any number of ways. As an example, the emit::err::as_ref
function can be used to convert an anyhow::Error
into an impl std::error::Error
:
#![allow(unused)] fn main() { extern crate anyhow; extern crate emit; fn write_to_file(bytes: &[u8]) -> Result<(), anyhow::Error> { Err(anyhow::Error::msg("the file is in an invalid state")) } if let Err(err) = write_to_file(b"Hello") { emit::warn!("file write failed: {err: emit::err::as_ref(&err)}"); } }
Errors on spans
The #[span]
macro can automatically capture errors from fallible functions. See Fallible functions for details.