Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix anyhow with_context loss other backtrace #513

Closed
wants to merge 1 commit into from

Conversation

taikulawo
Copy link
Contributor

  1. Fix with_context loss command line args.
    from anyhow docs

When you print an error object using "{}" or to_string(), only the outermost
/// underlying error or context is printed, not any of the lower level causes.
/// This is exactly as if you had called the Display impl of the error from
/// which you constructed your anyhow::Error.
///
/// console /// Failed to read instrs from ./path/to/instrs.json ///
///
/// To print causes as well using anyhow's default formatting of causes, use the
/// alternate selector "{:#}".

So even we use

.with_context(|| {
      format!(
          "Command `{}` failed ({})",
          format_command(&cmd),
          output.status
      )
  })
  .with_context(|| {
      format!(
          "Failed to compile {} from {}",
          out.display(),
          source.display()
      )
  });

we are still use to_string to format anyhow error, which cause loss anyhow command line context.

we should better change

let dir = tempdir().map_err(|e| Error::Build(e.to_string()))?;

to

let dir = tempdir().map_err(|e| Error::Build(format!("{:#}", e))?;

But more nice method is change Error::Build(String) to Error::Build(anyhow::Error), that's 2. Feature

  1. Feature: replace Error::Build(String) to Error::Build(anyhow::Error), keep anyhow error format to make beauty print
    image

Copy link
Collaborator

@danielocfb danielocfb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for improving the error reporting. May I ask why you adjusted Build but not Generate? The same issue seems to exist there. Also, please clean up the history as per the contribution guidelines.

@@ -88,7 +89,7 @@ mod test;
#[derive(Error, Debug)]
pub enum Error {
#[error("Error building BPF object file: {0}")]
Build(String),
Build(#[from] anyhow::Error),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe this should have a #[from] annotation. There is nothing about this variant that is tied to anyhow's Error. What happens if we were to switch the Generate variant over to using anyhow's Error as well? Now we are suddenly implicitly converting anyhow errors into Build, right? That seems wrong. #[from] is meant for cases where there is a clear relationship between a unique error type and the thing stored in the variant.

Furthermore, I believe it should have the #[source] annotation and omit {0} in the error description. Otherwise, that will just cause duplicate information from what I understand, depending on how formatting is done.

Copy link
Contributor Author

@taikulawo taikulawo Jul 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, #[from] should be removed. we can use anyhow::Error directly without call into(). Generate can also use anyhow::Error if you prefer, I will do.

If you care duplicate infomation, there shouldn't have #[error("Error generating skeleton: {0}")] or #[error("Error building BPF object file: {0}")], Build/Generate always have that semantic

I have change bothBuild/Generate to #[error(transparent)] to forward Build/Generate to underlying anyhow::Error

Copy link
Contributor Author

@taikulawo taikulawo Jul 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#[error("...")] only generate Display trait not Debug, Error building BPF object file: show when you print like {}, e, but context and backtrace only show when you {:?}, e

In the most scene, libbpf-cargo only be used in build.rs, so Debug mostly used

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I am not sure #[error(transparent)] is what we want, though. We still want to convey what went wrong (building or generating), otherwise why do we keep this error type to begin with?

So I'd think we want to keep printing the "Error generating skeleton" error string but should leave out the {0} part (at least if we use the #[source] annotation as well, which would be my preference).

@taikulawo
Copy link
Contributor Author

Thanks for improving the error reporting. May I ask why you adjusted Build but not Generate? The same issue seems to exist there. Also, please clean up the history as per the contribution guidelines.

I want to improve BPF build error report in BPF build progress, Generate progress is self-contained, less likely to make a mistakes

@taikulawo taikulawo force-pushed the master branch 2 times, most recently from abe55cb to 74d24f3 Compare July 13, 2023 03:47
@danielocfb
Copy link
Collaborator

Thanks for improving the error reporting. May I ask why you adjusted Build but not Generate? The same issue seems to exist there. Also, please clean up the history as per the contribution guidelines.

I want to improve BPF build error report in BPF build progress, Generate progress is self-contained, less likely to make a mistakes

Let's just do it? None of this is a reason to not convert it. Now every reasonable person will wonder why one variant contains an error and the other variant a string.

@taikulawo
Copy link
Contributor Author

All done
example output

image

but we would better keep {0}, or we will just get Error building BPF object file. It don't said which file failed like Error file not found, confusing user.

@danielocfb
Copy link
Collaborator

but we would better keep {0}, or we will just get Error building BPF object file. It don't said which file failed like Error file not found, confusing user.

I mean...it's an error chain. If you don't print the chain you won't get all the details. That's kind of the point. Here is the official stance: rust-lang/project-error-handling#27 (comment)

2.generate error also use anyhow::error
Copy link
Collaborator

@danielocfb danielocfb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems fine to me, thanks!

@danielocfb
Copy link
Collaborator

I added a CHANGELOG entry and a proper commit description and merge the change. I think we should consider adding a custom Debug impl for the Error type to get rid of this Build( / Generate( prefix in the output, but this change should be able to stand on its own. Feel free to open a pull request if you want to take care of it. Thanks again.

@danielocfb danielocfb closed this Jul 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants