Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upadd "Obtain backtrace of complex error scenarios" example #325
Conversation
This comment has been minimized.
This comment has been minimized.
|
Hello @budziq Here is my attempt to show a "complex" backtrace with a relatively short code. Let me know if it is a good candidate for this issue. Edit: the snippet generates an error on purpose and it looks like the CI is not happy about it. |
ludwigpacifici
referenced this pull request
Oct 11, 2017
Closed
add "Avoid discarding errors during error conversions" example #215
budziq
requested changes
Oct 11, 2017
|
Thanks! Few comments below. I'll do a more thorough review tommorow |
| @@ -1109,6 +1171,7 @@ fn main() { | |||
| [`BufRead::lines`]: https://doc.rust-lang.org/std/io/trait.BufRead.html#method.lines | |||
| [`BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html | |||
| [`BufReader`]: https://doc.rust-lang.org/std/io/struct.BufReader.html | |||
| [`chain_err`]: https://docs.rs/error-chain/0.11.0/error_chain/index.html#chaining-errors | |||
This comment has been minimized.
This comment has been minimized.
| Ok(()) | ||
| } | ||
| quick_main!(run); |
This comment has been minimized.
This comment has been minimized.
budziq
Oct 11, 2017
Collaborator
lets not use the quick_main! here as it will error out the application.
lets have a regular main in addition to run to showcase usage of
backtrace in order to iterate over the backtrace
budziq
reviewed
Oct 11, 2017
| Ok(color) | ||
| } | ||
| # type Hex = u32; |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
ludwigpacifici
Oct 14, 2017
Author
Contributor
I don't understand you comment. Can you give more details?
This comment has been minimized.
This comment has been minimized.
ludwigpacifici
Oct 14, 2017
•
Author
Contributor
custom Display impl for Rgb
Ah, I think I get it :-) Do you mean something like:
let color = Rgb{...};
println!("#{}", color); // Prints #66FFCCrgb_to_hex will be replace by the Display impl for Rgb?
Edit: Will it make more sense to implement std::fmt::UpperHex?
This comment has been minimized.
This comment has been minimized.
budziq
requested changes
Oct 12, 2017
|
Ok, review is finished. Sorry for doing it in parts |
| .deserialize() | ||
| .nth(0) | ||
| .ok_or("Cannot deserialize the first CSV record")? | ||
| .chain_err(|| "Cannot deserialize RGB color")?; |
This comment has been minimized.
This comment has been minimized.
budziq
Oct 12, 2017
Collaborator
not sure about using both ok_or and chain_err at the same time One of these would suffice.
This comment has been minimized.
This comment has been minimized.
ludwigpacifici
Oct 16, 2017
Author
Contributor
I have to use ok_or and chain_err to make it work. I tried to be concise, maybe too much? Here is a more verbose version:
let mut reader = csv::Reader::from_reader(csv_data);
let mut it = reader.deserialize();
let option = it.nth(0);
if let Some(inner) = option {
// Notice that we need to provide a type hint for automatic deserialization.
let color: Rgb = inner.chain_err(|| "Cannot deserialize RGB color")?;
Ok(color)
} else {
Err(From::from("Cannot deserialize the first CSV record"))
}Documentation I used: https://docs.rs/csv/1.0.0-beta.4/csv/index.html#example-with-serde
This comment has been minimized.
This comment has been minimized.
budziq
Oct 17, 2017
Collaborator
Nope, the original is very good. Honestly my bad I have made this review a too cursory one.
This comment has been minimized.
This comment has been minimized.
ludwigpacifici
Oct 21, 2017
Author
Contributor
No worries @budziq :-) It's good you question my rust code because I am beginner and cookbook PR teaches me a lot.
| # } | ||
| # | ||
| fn run() -> Result<()> { | ||
| let csv = "red,blue,green |
This comment has been minimized.
This comment has been minimized.
budziq
Oct 12, 2017
Collaborator
to bump the size of our backtrace we can use a file input. Provide an associate function from_path which would in turn call associated function from_reader (formerly read_rgb_from_csv)
This comment has been minimized.
This comment has been minimized.
ludwigpacifici
Oct 16, 2017
•
Author
Contributor
Not sure I understand this comment. from_path is already provided by the csv crate.
The snippet would look like:
let color: Rgb = csv::ReaderBuilder::new()
.from_path("color.csv")
.chain_err(|| "Cannot read CSV file")?
.deserialize()
.nth(0)
.ok_or("Cannot deserialize the first CSV record")?
.chain_err(|| "Cannot deserialize RGB color")?;Then it leads to a shorter error stack, if the file does not exist:
Error level - description
└> 0 - Cannot read CSV file
└> 1 - No such file or directory (os error 2)
└> 2 - No such file or directory (os error 2)
Am I missing something?
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
ludwigpacifici
Oct 21, 2017
Author
Contributor
That's alright. Maybe the following snippet will make the example more Rust idiomatic?
impl Rgb {
fn from_reader(csv_data: &[u8]) -> Result<Rgb> {
// move code of read_rgb_from_csv here
}
}and in the run function, the line will be:
let rgb = Rgb::from_reader(csv.as_bytes()).chain_err(|| "Cannot read CSV data")?;
The error stack is unchanged. What do you think?
This comment has been minimized.
This comment has been minimized.
|
|
||
| [![error-chain-badge]][error-chain] [![cat-rust-patterns-badge]][cat-rust-patterns] | ||
|
|
||
| Extend errors by appending new errors via [`chain_err`]. It provides a |
This comment has been minimized.
This comment has been minimized.
budziq
Oct 12, 2017
Collaborator
I would start with mentioning that we have a complex error handling scenario and we present a backtrace from it.
|
|
||
| Extend errors by appending new errors via [`chain_err`]. It provides a | ||
| better context to understand an error in a form of a backtrace. The | ||
| below recipes attemps to deserialize the value `256` into a `u8`. An |
This comment has been minimized.
This comment has been minimized.
budziq
Oct 12, 2017
Collaborator
Also I would present the example backtrace output after the code snippet.
This comment has been minimized.
This comment has been minimized.
ludwigpacifici
Oct 14, 2017
Author
Contributor
Isn't it redundant if the reader hit the play button?
This comment has been minimized.
This comment has been minimized.
budziq
Oct 14, 2017
Collaborator
We will be only able to (easily) simulate one error scenario (file not found). We might decide to show backtraces from other error scenarios too. But we will see how the example unfolds :)
This comment has been minimized.
This comment has been minimized.
|
Thanks @budziq for your review. I am on a weekend, I expect to correct the PR beginning of the week. |
ludwigpacifici
force-pushed the
ludwigpacifici:master
branch
from
f257cae
to
168fea6
Oct 16, 2017
This comment has been minimized.
This comment has been minimized.
|
I updated the PR following most of your comments. Still open to discussion:
|
budziq
requested changes
Oct 17, 2017
|
That is an exemplary work @ludwigpacifici ! |
| eprintln!("{:?}", backtrace); | ||
| } | ||
| ::std::process::exit(1); |
This comment has been minimized.
This comment has been minimized.
budziq
Oct 17, 2017
Collaborator
I'd just drop this line to make our CI happy or make the example no_run. We can always write a comment here mentioning that we would normally handle the errors or leave the app here with and error.
This comment has been minimized.
This comment has been minimized.
ludwigpacifici
Oct 21, 2017
Author
Contributor
The CI is trying to execute the recipes by default, meaning it checks the code compiles at least. If no_run is set, is the code still compiled?
I try to understand which is better no_run vs make the code return a success code.
This comment has been minimized.
This comment has been minimized.
budziq
Oct 22, 2017
Collaborator
no_run - compiles the code but does not run it
ignore - does not compile it at all
I'd probably go with leaving this example runnable but removing the ::std::process::exit(1); but I'll leave it up to you.
This comment has been minimized.
This comment has been minimized.
ludwigpacifici
Oct 22, 2017
Author
Contributor
Thanks for the listing.
I'd probably go with leaving this example runnable but removing the ::std::process::exit(1);
Yes, I'll do that
ludwigpacifici
force-pushed the
ludwigpacifici:master
branch
from
168fea6
to
09f66e8
Oct 22, 2017
This comment has been minimized.
This comment has been minimized.
|
CI is happy :-) One question left on my side: #325 (comment), and waiting for your suggestions, if you have any. |
ludwigpacifici
force-pushed the
ludwigpacifici:master
branch
from
09f66e8
to
51201e5
Oct 23, 2017
This comment has been minimized.
This comment has been minimized.
|
I noticed removing |
This comment has been minimized.
This comment has been minimized.
|
Stderr is printed only if playground returns process failure Let's keep the example runnable and possibly submit a bug report to mdbook (we can also modify it lolly in cookbook but I'd prefer to to avoid it) |
This comment has been minimized.
This comment has been minimized.
|
Alright @budziq. In that case, the PR looks fine on my side. I will raise an issue to mdbook. Should I cc you? |
budziq
merged commit b8aab79
into
rust-lang-nursery:master
Oct 23, 2017
This comment has been minimized.
This comment has been minimized.
|
Thanks @ludwigpacifici! Yep, please cc me on mdbook issue. I'll ad it to my ever expanding todo list ;). |
This comment has been minimized.
This comment has been minimized.
|
or better yet please create the issue in cookbook for now untill we come up with reasonable solution to propose. |
This comment has been minimized.
This comment has been minimized.
|
Thanks for your time @budziq I will put it on the ever expanding list of the rust-cookbook :-) |
ludwigpacifici commentedOct 9, 2017
Issue #216