diff options
author | har7an <99636919+har7an@users.noreply.github.com> | 2022-12-07 07:51:23 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-07 07:51:23 +0000 |
commit | 81287a276f62d4ca98c9fa1b76332db074a13cc5 (patch) | |
tree | f23a2103953797d28480d22750f24287318a7e61 /zellij-utils | |
parent | fd7a5398cd0145f9b3c59ac6382cc2883a90b92a (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')
-rw-r--r-- | zellij-utils/src/errors.rs | 32 |
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)`. |