summaryrefslogtreecommitdiffstats
path: root/zellij-utils/src/errors.rs
diff options
context:
space:
mode:
authorhar7an <99636919+har7an@users.noreply.github.com>2022-12-07 07:51:23 +0000
committerGitHub <noreply@github.com>2022-12-07 07:51:23 +0000
commit81287a276f62d4ca98c9fa1b76332db074a13cc5 (patch)
treef23a2103953797d28480d22750f24287318a7e61 /zellij-utils/src/errors.rs
parentfd7a5398cd0145f9b3c59ac6382cc2883a90b92a (diff)
errors: Maintain caller location in `to_log` (#1994)
* utils/errors: Add caller location to `to_log` by building the log record manually and filling in the callers file and line manually. It is currently not possible to determine a callers module, hence the module is now set to "???" in all log entries logged this way. Nonetheless, the file and line number are sufficient to find the logs source. * utils/errors: Reimplement `to_log` default implementation in the `LoggableError` trait. * changelog: Add PR #1994 errors: Maintain caller location in `to_log`
Diffstat (limited to 'zellij-utils/src/errors.rs')
-rw-r--r--zellij-utils/src/errors.rs32
1 files changed, 25 insertions, 7 deletions
diff --git a/zellij-utils/src/errors.rs b/zellij-utils/src/errors.rs
index fe517783e..07947dd12 100644
--- a/zellij-utils/src/errors.rs
+++ b/zellij-utils/src/errors.rs
@@ -96,15 +96,33 @@ pub trait LoggableError<T>: Sized {
#[track_caller]
fn print_error<F: Fn(&str)>(self, fun: F) -> Self;
- /// Convenienve function, calls `print_error` with the closure `|msg| log::error!("{}", msg)`.
- // Dev note:
- // Currently this hides the location of the caller, because it will show this very line as
- // "source" of the logging call. This isn't correct, because it may have been called by other
- // functions, too. To track this, we need to attach `#[track_caller]` to the closure below,
- // which isn't stabilized yet: https://github.com/rust-lang/rust/issues/87417
+ /// Convenienve function, calls `print_error` and logs the result as error.
+ ///
+ /// This is not a wrapper around `log::error!`, because the `log` crate uses a lot of compile
+ /// time macros from `std` to determine caller locations/module names etc. Since these are
+ /// resolved at compile time in the location they are written, they would always resolve to the
+ /// location in this function where `log::error!` is called, masking the real caller location.
+ /// Hence, we build the log message ourselves. This means that we lose the information about
+ /// the calling module (Because it can only be resolved at compile time), however the callers
+ /// file and line number are preserved.
#[track_caller]
fn to_log(self) -> Self {
- self.print_error(|msg| log::error!("{}", msg))
+ let caller = std::panic::Location::caller();
+ self.print_error(|msg| {
+ // Build the log entry manually
+ // NOTE: The log entry has no module path associated with it. This is because `log`
+ // gets the module path from the `std::module_path!()` macro, which is replaced at
+ // compile time in the location it is written!
+ log::logger().log(
+ &log::Record::builder()
+ .level(log::Level::Error)
+ .args(format_args!("{}", msg))
+ .file(Some(caller.file()))
+ .line(Some(caller.line()))
+ .module_path(None)
+ .build(),
+ );
+ })
}
/// Convenienve function, calls `print_error` with the closure `|msg| eprintln!("{}", msg)`.