diff --git a/README.md b/README.md index 0d38a56..ea5a7ff 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,13 @@ # chainerror -Read the [Tutorial](https://haraldh.github.io/chainerror/) + +`chainerror` provides an error backtrace like `failure` without doing a real backtrace, so even after you `strip` your +binaries, you still have the error backtrace. + +`chainerror` uses `.source()` of `std::error::Error` along with `line()!` and `file()!` to provide a nice debug error backtrace. +It encapsulates all types, which have `Display + Debug` and can store the error cause internally. + +Along with the `ChainError` struct, `chainerror` comes with some useful helper macros to save a lot of typing. + +Debug information is worth it! + +For an introduction read the [Tutorial](https://haraldh.github.io/chainerror/) diff --git a/booksrc/tutorial1.md b/booksrc/tutorial1.md index 12bd9cd..689d2a4 100644 --- a/booksrc/tutorial1.md +++ b/booksrc/tutorial1.md @@ -1,3 +1,11 @@ +## Simple String Errors + +The most simplest of doing error handling in rust is by returning `String` as a `Box`. + +As you can see by running the example, this only prints out the last `Error`. + +If the rust `main` function returns an Err(), this Err() will be displayed with `std::fmt::Debug`. + ~~~rust {{#include ../examples/tutorial1.rs:2:}} ~~~ \ No newline at end of file diff --git a/booksrc/tutorial10.md b/booksrc/tutorial10.md index 7be3cb3..f84ea21 100644 --- a/booksrc/tutorial10.md +++ b/booksrc/tutorial10.md @@ -1,3 +1,7 @@ +## ErrorKind to the rescue + +[TBD] + ~~~rust use crate::chainerror::*; {{#include ../examples/tutorial10.rs:2:}} diff --git a/booksrc/tutorial11.md b/booksrc/tutorial11.md index 0af9cea..f433492 100644 --- a/booksrc/tutorial11.md +++ b/booksrc/tutorial11.md @@ -1,3 +1,7 @@ +## Debug for the ErrorKind + +[TBD] + ~~~rust use crate::chainerror::*; {{#include ../examples/tutorial11.rs:2:}} diff --git a/booksrc/tutorial2.md b/booksrc/tutorial2.md index dc34731..2d40609 100644 --- a/booksrc/tutorial2.md +++ b/booksrc/tutorial2.md @@ -1,3 +1,9 @@ +## Simple Chained String Errors + +Now with the help of the `chainerror` crate, we can have a nicer output. + +Press the play button in the upper right corner and see the nice debug output. + ~~~rust use crate::chainerror::*; {{#include ../examples/tutorial2.rs:2:}} @@ -5,4 +11,21 @@ use crate::chainerror::*; # mod chainerror { {{#includecomment ../src/lib.rs}} # } -~~~ \ No newline at end of file +~~~ + +### What did we do here? + +~~~rust,ignore +{{#include ../examples/tutorial2.rs:11:13}} +~~~ + +The macro `cherr!(cause, newerror)` stores `cause` as the source/cause of `newerror` and returns +`newerror`, along with the filename (`file!()`) and line number (`line!()`). + +`Err(e)?` then returns the error `e` applying `e.into()`, so that we +again have a `Err(Box)` as a result. + +The `Debug` implementation of `ChainError` (which is returned by `cherr!()`) +prints the `Debug` of `T` prefixed with the stored filename and line number. + +`ChainError` is in our case `ChainError`. \ No newline at end of file diff --git a/booksrc/tutorial3.md b/booksrc/tutorial3.md index ab61a8d..b27b4e7 100644 --- a/booksrc/tutorial3.md +++ b/booksrc/tutorial3.md @@ -1,3 +1,7 @@ +## Mapping Errors + +Now let's get more rust idiomatic by using `.map_err()`. + ~~~rust use crate::chainerror::*; {{#include ../examples/tutorial3.rs:2:}} @@ -5,4 +9,22 @@ use crate::chainerror::*; # mod chainerror { {{#includecomment ../src/lib.rs}} # } -~~~ \ No newline at end of file +~~~ + +If you compare the output to the previous example, you will see, +that: + +~~~ +Error: src/main.rs:19: "func1 error" +~~~ + +changed to just: + +~~~ +src/main.rs:16: "func1 error" +~~~ + +This is, because we caught the error of `func1()` in `main()` and print it out ourselves. + +We can now control, whether to output in `Debug` or `Display` mode. +Maybe depending on `--debug` as a CLI argument. \ No newline at end of file diff --git a/booksrc/tutorial4.md b/booksrc/tutorial4.md index 7744218..788efdc 100644 --- a/booksrc/tutorial4.md +++ b/booksrc/tutorial4.md @@ -1,3 +1,13 @@ +## Saving coding chars + +Because decorating an error with more information should not +let you jump through hoops, `chainerror` has a quick macro for that. + +`mstrerror!()` fits right into `.map_err()` letting you quickly add +more debug strings. + +`mstrerror!()` even understands `format!()` syntax like `println!()`. + ~~~rust use crate::chainerror::*; {{#include ../examples/tutorial4.rs:2:}} diff --git a/booksrc/tutorial5.md b/booksrc/tutorial5.md index ed8ae7a..7d792df 100644 --- a/booksrc/tutorial5.md +++ b/booksrc/tutorial5.md @@ -1,3 +1,8 @@ +## The source() of Errors + +Sometimes you want to inspect the `source()` of an `Error`. +`chainerror` implements `std::error::Error::source()`, so you can get the cause of an error. + ~~~rust use crate::chainerror::*; {{#include ../examples/tutorial5.rs:2:}} @@ -5,4 +10,10 @@ use crate::chainerror::*; # mod chainerror { {{#includecomment ../src/lib.rs}} # } -~~~ \ No newline at end of file +~~~ + +Note, that we changed the output of the error in `main()` from `Debug` to `Display`, so we don't see +the error backtrace with filename and line number. + +To enable the `Display` backtrace, you have to enable the feature `display-cause` for `chainerror`. + \ No newline at end of file diff --git a/booksrc/tutorial6.md b/booksrc/tutorial6.md index 8483c94..db4e977 100644 --- a/booksrc/tutorial6.md +++ b/booksrc/tutorial6.md @@ -1,3 +1,7 @@ +## Downcast the Errors + +[TBD] + ~~~rust use crate::chainerror::*; {{#include ../examples/tutorial6.rs:2:}} diff --git a/booksrc/tutorial7.md b/booksrc/tutorial7.md index 6e5e544..f7bcbdb 100644 --- a/booksrc/tutorial7.md +++ b/booksrc/tutorial7.md @@ -1,3 +1,7 @@ +## The root cause of all Errors + +[TBD] + ~~~rust use crate::chainerror::*; {{#include ../examples/tutorial7.rs:2:}} diff --git a/booksrc/tutorial8.md b/booksrc/tutorial8.md index 3ecb4e7..a8030eb 100644 --- a/booksrc/tutorial8.md +++ b/booksrc/tutorial8.md @@ -1,3 +1,7 @@ +## Finding an Error cause + +[TBD] + ~~~rust use crate::chainerror::*; {{#include ../examples/tutorial8.rs:2:}} diff --git a/booksrc/tutorial9.md b/booksrc/tutorial9.md index 09e20c3..4941531 100644 --- a/booksrc/tutorial9.md +++ b/booksrc/tutorial9.md @@ -1,3 +1,7 @@ +## Selective Error Handling + +[TBD] + ~~~rust use crate::chainerror::*; {{#include ../examples/tutorial9.rs:2:}} diff --git a/examples/tutorial4.rs b/examples/tutorial4.rs index e55aaed..f6d8cba 100644 --- a/examples/tutorial4.rs +++ b/examples/tutorial4.rs @@ -8,7 +8,8 @@ fn do_some_io() -> Result<(), Box> { } fn func2() -> Result<(), Box> { - do_some_io().map_err(mstrerr!("func2 error"))?; + let filename = "foo.txt"; + do_some_io().map_err(mstrerr!("Error reading '{}'", filename))?; Ok(()) }