slog-rs / slog

Structured, contextual, extensible, composable logging for Rust
https://slog.rs/
Apache License 2.0
1.58k stars 95 forks source link

Support `ErrorRef` in `#` error formatter #328

Closed demurgos closed 10 months ago

demurgos commented 10 months ago

This commit adds support for error references for the # error formatter from the kv macro. If the passed error is an owned error value it uses ErrorValue; otherwise if it can be dereferenced into an error then it uses ErrorRef.

The way to detect if the value implements Error directly or if it's an error reference is based on auto-deref coercion as described in the following articles:

I believe it to be fully backwards compatible with existing uses of #. This provides a short-hand for the ErrorRef wrapper in most common cases. However, it does not support temporary lifetime extension.

This means that the following example needs to introduce a temporary binding to use the shorthand syntax:

// explicit ref with lifetime extension
info!(logger, "not found"; "error" => ErrorRef(&std::io::Error::from(std::io::ErrorKind::NotFound)));
// `#` shorthand with temporary binding
let error = std::io::Error::from(std::io::ErrorKind::NotFound);
info!(logger, "not found"; "error" => #&error);

In practice, this use case is not an issue. Such a temporary can instead be passed by value (the reference is useless) through ErrorValue. There are discussions in Zulip to support explicit lifetime extensions and support this use case in the future.

Make sure to:

This is a follow up to https://github.com/slog-rs/slog/pull/327 to add support for the macro shorthand #. I sent it in its own PR as the logic is more complex and I don't want to block the simple error reference wrapper because of the macro logic. Commit with macro support

Techcable commented 10 months ago

This is brilliant!! I'm not the greatest with traditional macros, so I'm not 100% sure about compatibility either.

I will rebase this to be compatible with the last PR.

demurgos commented 10 months ago

Thank you for reviewing and merging my changes