-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Add error::Report type #90174
Add error::Report type #90174
Conversation
r? @m-ou-se (rust-highfive has picked a reviewer for you, use r? to override) |
library/std/src/error.rs
Outdated
|
||
/// Enable pretty-printing the report. | ||
#[unstable(feature = "error_reporter", issue = "90172")] | ||
pub fn pretty(mut self) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we have any 'builder pattern' functions in std right now that take and return self by value. Instead, they take &mut self
and return &mut Self
. That way, you can also use them without chaining them, as they modify the original object, but also allow chaining.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's definitely preferable to have this one done by value, because otherwise you can end up with common usages breaking. Our original version used &mut Self
but broke in the following trivial example:
let report = Report::new(error).pretty(); // error: reference to temporary
println!("{}", report);
Report is designed so that you're always going to create it and then use it immediately, so being able to mutate a pre-defined report is never going to be useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Report is designed so that you're always going to create it and then use it immediately, so being able to mutate a pre-defined report is never going to be useful.
Then why is it a problem that your example breaks, if you're not supposed to store it for later use?
Your example makes me think that it would be useful to be able to do things like:
let mut report = Report::new(error);
if opts.verbose_errors {
report.pretty(true);
}
println!("{}", report);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I agree, I'd write that like this:
let report = Report::new(error).pretty(opts.verbose_errors);
println!("{}", report);
Then why is it a problem that your example breaks, if you're not supposed to store it for later use?
The issue to me is that I don't want to be forced to add a bunch of extra lines or inline the entire thing in a println in order to have it compile, if it it was returned by reference my example could only be written like this:
let mut report = Report::new(error);
report.pretty(opts.verbose_errors);
println!("{}", report);
or
println!("{}", report.pretty(opts.verbose_errors));
In my experience using Report
so far I have found that it tends to be more annoying to use when it returned &mut Self
and when I inlined the method calls they often ended up having to be spread over multiple lines and made the code look much harder to read for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the very least, it seems like show_backtrace
and pretty
should be reverted to accept a boolean (we had this in a previous iteration, but ended up removing it).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(This is why in the other cases the builder type is different type than the type you end up building. Then the builder type doesn't need to contain any references or resources yet, such that (&mut self) -> &mut Self
can be used, and only an .open()
, .spawn(..)
, or w/e at the end will make the object you wanted to make, which might end up borrowing things into the newly created object.
But having two types in this case might get a bit annoying.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, I think its particularly important that fallible_fn().map_err(Report::new).unwrap()
be usable, so forcing a .build()
call at the end feels a little awkward to me.
Can you add some tests? There's a doc example, but it doesn't check the output. (And it'd be good to test what happens with multiple sources, multi-line errors, etc., as those are broken now.) |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like there's a few more bugs:
Empty lines are dropped in sources:
line 1
line 3
Caused by:
0: line 1
line 3
1: line 1
line 3
And with a single source, multi-line indentation breaks:
line 1
line 2
Caused by:
line 1
line 2
Co-authored-by: Mara Bos <[email protected]>
Co-authored-by: Mara Bos <[email protected]>
Almost done resolving the recent round of comments but I have a couple of style questions that came up during the implementation that I could use some input on. First, I want to make sure we have the right level of indentation setup for our multiline errors so they match up nicely with the output of Here's the current version with the changes I made and one source error:
And with 2 or more sources
This is identical to the formatting rules for My preferred version would look like this
and
|
Add `std::error::Report` type This is a continuation of rust-lang#90174, split into a separate PR since I cannot push to `@seanchen1991` 's fork
Add `std::error::Report` type This is a continuation of rust-lang#90174, split into a separate PR since I cannot push to ``@seanchen1991`` 's fork
Add `std::error::Report` type This is a continuation of rust-lang#90174, split into a separate PR since I cannot push to ```@seanchen1991``` 's fork
Add `std::error::Report` type This is a continuation of rust-lang#90174, split into a separate PR since I cannot push to ````@seanchen1991```` 's fork
Add `std::error::Report` type This is a continuation of rust-lang#90174, split into a separate PR since I cannot push to `````@seanchen1991````` 's fork
Add `std::error::Report` type This is a continuation of rust-lang#90174, split into a separate PR since I cannot push to ``````@seanchen1991`````` 's fork
Add `std::error::Report` type This is a continuation of rust-lang#90174, split into a separate PR since I cannot push to ```````@seanchen1991``````` 's fork
☔ The latest upstream changes (presumably #92844) made this pull request unmergeable. Please resolve the merge conflicts. |
Merged as #91938, closing this PR now |
This implements
std::error::Report
, a wrapper around an error that exposes the entire error chain, along with options to format the output of the report as either a single line or as multiple lines.Tracking issue: #90172.