Skip to content

Commit

Permalink
update original
Browse files Browse the repository at this point in the history
  • Loading branch information
funkill committed Nov 30, 2024
1 parent 209d89b commit 9a56456
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 115 deletions.
54 changes: 27 additions & 27 deletions rust-cookbook/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rust-cookbook"
version = "1.0.0"
version = "1.1.0"
authors = ["Brian Anderson <[email protected]>", "Andrew Gauger <[email protected]>"]
edition = "2018"
license = "MIT/Apache-2.0"
Expand All @@ -21,7 +21,6 @@ crossbeam-channel = "0.3.9"
csv = "1.0"
data-encoding = "2.1.0"
env_logger = "0.11.3"
error-chain = "0.12"
flate2 = "1.0"
glob = "0.3"
image = "0.20"
Expand All @@ -30,42 +29,43 @@ log = "0.4"
log4rs = "0.8"
memmap = "0.7"
mime = "0.3"
nalgebra = { version = "0.16.12", features = ["serde-serialize"] }
ndarray = { version = "0.13", features = ["approx"] }
num = "0.2"
num_cpus = "1.8"
percent-encoding = "2.1"
petgraph = "0.4"
postgres = "0.17.2"
rand = "0.8.0"
rand_distr = "0.4.0"
rayon = "1.0"
regex = "1.0"
reqwest = { version = "0.10", features = ["blocking", "json", "stream"] }
ring = "0.16.11"
rusqlite = { version = "0.25", features = ["chrono"] }
nalgebra = { version = "0.33", features = ["serde-serialize"] }
ndarray = { version = "0.16", features = ["approx"] }
num = "0.4"
num_cpus = "1.16"
percent-encoding = "2.3"
petgraph = "0.6"
postgres = "0.19"
rand = "0.8"
rand_distr = "0.4"
rayon = "1.10"
regex = "1.11"
reqwest = { version = "0.12", features = ["blocking", "json", "stream"] }
ring = "0.17"
rusqlite = { version = "0.32", features = ["chrono"] }
same-file = "1.0"
select = "0.4"
semver = "0.9"
select = "0.6"
semver = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_derive = "1.0"
serde_json = "1.0"
tar = "0.4.12"
tempfile = "3.1"
threadpool = "1.6"
toml = "0.4"
tokio = { version = "0.2", features = ["full"] }
tar = "0.4"
tempfile = "3.14"
thiserror = "2"
threadpool = "1.8"
toml = "0.8"
tokio = { version = "1", features = ["full"] }
unicode-segmentation = "1.2.1"
url = "2.1"
walkdir = "2.0"
url = "2.5"
walkdir = "2.5"

[target.'cfg(target_os = "linux")'.dependencies]
syslog = "5.0"

[build-dependencies]
skeptic = "0.13"
walkdir = "2.0"
walkdir = "2.5"

[dev-dependencies]
skeptic = "0.13"
walkdir = "2.0"
walkdir = "2.5"
82 changes: 11 additions & 71 deletions rust-cookbook/src/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,78 +96,15 @@ documentation on [docs.rs], and is often the next documentation you
should read after deciding which crate suites your purpose.

## A note about error handling
Rust has [`std::error::Trait`] which is implemented to handle exceptions.
Handling multiple types of these traits can be simplified using [`anyhow`]
or specified with an `enum` which macros exist to make this easier within
[`thiserror`] for library authors.

Error handling in Rust is robust when done correctly, but in today's
Rust it requires a fair bit of boilerplate. Because of this one often
sees Rust examples filled with `unwrap` calls instead of proper error
handling.

Since these recipes are intended to be reused as-is and encourage best
practices, they set up error handling correctly when there are
`Result` types involved.

The basic pattern we use is to have a `fn main() -> Result`.

The structure generally looks like:

```rust,edition2018
use error_chain::error_chain;
use std::net::IpAddr;
use std::str;
error_chain! {
foreign_links {
Utf8(std::str::Utf8Error);
AddrParse(std::net::AddrParseError);
}
}
fn main() -> Result<()> {
let bytes = b"2001:db8::1";
// Bytes to string.
let s = str::from_utf8(bytes)?;
// String to IP address.
let addr: IpAddr = s.parse()?;
println!("{:?}", addr);
Ok(())
}
```

This is using the `error_chain!` macro to define a custom `Error` and
`Result` type, along with automatic conversions from two standard
library error types. The automatic conversions make the `?` operator
work.

For the sake of readability error handling boilerplate is hidden by
default like below. In order to read full contents click on the
"Show hidden lines" (<i class="fa fa-eye"></i>) button located in the top
right corner of the snippet.

```rust,edition2018
# use error_chain::error_chain;
use url::{Url, Position};
#
# error_chain! {
# foreign_links {
# UrlParse(url::ParseError);
# }
# }
fn main() -> Result<()> {
let parsed = Url::parse("https://httpbin.org/cookies/set?k2=v2&k1=v1")?;
let cleaned: &str = &parsed[..Position::AfterPath];
println!("cleaned: {}", cleaned);
Ok(())
}
```

For more background on error handling in Rust, read [this page of the
Rust book][error-docs] and [this blog post][error-blog].
Error chain has been shown in this book for historical reasons before Rust
`std` and crates represented macro use as a preference. For more background
on error handling in Rust, read [this page of the Rust book][error-docs]
and [this blog post][error-blog].

## A note about crate representation

Expand Down Expand Up @@ -199,4 +136,7 @@ as are crates that are pending evaluation.
[crates.io]: https://crates.io
[docs.rs]: https://docs.rs
[Cargo.toml]: http://doc.crates.io/manifest.html
[`anyhow`]: https://docs.rs/anyhow/latest/anyhow/
[`cargo-edit`]: https://github.com/killercup/cargo-edit
[`std::error::Trait`]: https://doc.rust-lang.org/std/error/trait.Error.html
[`thiserror`]: https://docs.rs/thiserror/latest/thiserror/
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ build = "build.rs"
cc = "1"

[dependencies]
error-chain = "0.11"
anyhow = "1"
```

### `build.rs`
Expand Down Expand Up @@ -56,16 +56,10 @@ void greet(const char* name) {
### `src/main.rs`
```rust,edition2018,ignore
use error_chain::error_chain;
use anyhow::Result;
use std::ffi::CString;
use std::os::raw::c_char;
error_chain! {
foreign_links {
NulError(::std::ffi::NulError);
Io(::std::io::Error);
}
}
fn prompt(s: &str) -> Result<String> {
use std::io::Write;
print!("{}", s);
Expand Down
8 changes: 4 additions & 4 deletions rust-cookbook/src/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

| Recipe | Crates | Categories |
|--------|--------|------------|
| [Composing errors with an enum][ex-thiserror] | [![thiserror-badge]][thiserror] | [![cat-rust-patterns-badge]][cat-rust-patterns] |
| [Dynamic errors with anyhow][ex-anyhow] | [![anyhow-badge]][anyhow] | [![cat-rust-patterns-badge]][cat-rust-patterns] |
| [Handle errors correctly in main][ex-error-chain-simple-error-handling] | [![error-chain-badge]][error-chain] | [![cat-rust-patterns-badge]][cat-rust-patterns] |
| [Avoid discarding errors during error conversions][ex-error-chain-avoid-discarding] | [![error-chain-badge]][error-chain] | [![cat-rust-patterns-badge]][cat-rust-patterns] |
| [Obtain backtrace of complex error scenarios][ex-error-chain-backtrace] | [![error-chain-badge]][error-chain] | [![cat-rust-patterns-badge]][cat-rust-patterns] |

[ex-thiserror]: errors/handle.html#thiserror
[ex-anyhow]: errors/handle.html#anyhow
[ex-error-chain-simple-error-handling]: errors/handle.html#handle-errors-correctly-in-main
[ex-error-chain-avoid-discarding]: errors/handle.html#avoid-discarding-errors-during-error-conversions
[ex-error-chain-backtrace]: errors/handle.html#obtain-backtrace-of-complex-error-scenarios

{{#include links.md}}
4 changes: 0 additions & 4 deletions rust-cookbook/src/errors/handle.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,4 @@

{{#include handle/main.md}}

{{#include handle/retain.md}}

{{#include handle/backtrace.md}}

{{#include ../links.md}}
45 changes: 44 additions & 1 deletion rust-cookbook/src/errors/handle/main.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,46 @@
## Handle errors correctly in main

[![anyhow-badge]][anyhow] [![cat-rust-patterns-badge]][cat-rust-patterns]
[![thiserror-badge]][thiserror] [![cat-rust-patterns-badge]][cat-rust-patterns]
[![error-chain-badge]][error-chain] [![cat-rust-patterns-badge]][cat-rust-patterns]

# Error Strategies (2024)

As recommended in Rust by Example, [`Box`ing errors] is seen as an easy
strategy for getting started.

```rust,edition2018
Box<dyn Error>
````
To understand what kind of error handling may be required study [Designing
error types in Rust] and consider [`thiserror`] for libraries or [`anyhow`] as
a maintained error aggregation option.
```rust,edition2018
use thiserror::Error;
#[derive(Error,Debug)]
pub enum MultiError {
#[error("🦀 got {0}")]
ErrorClass(String),
}
```

Application authors can compose enums using `anyhow` can import the `Result`
type from the crate to provide auto-`Box`ing behavior

```rust,edition2018,should_panic
use anyhow::Result;
fn main() -> Result<()> {
let my_string = "yellow".to_string();
let _my_int = my_string.parse::<i32>()?;
Ok(())
}
```

# Error Chain (2015-2018)
Handles error that occur when trying to open a file that does not
exist. It is achieved by using [error-chain], a library that takes
care of a lot of boilerplate code needed in order to [handle errors in Rust].
Expand All @@ -17,7 +56,7 @@ first number. Returns uptime unless there is an error.
Other recipes in this book will hide the [error-chain] boilerplate, and can be
seen by expanding the code with the ⤢ button.

```rust,edition2018
```rust,edition2018,ignore
use error_chain::error_chain;
use std::fs::File;
Expand Down Expand Up @@ -49,9 +88,13 @@ fn main() {
}
```

[`anyhow`]: https://docs.rs/anyhow/latest/anyhow/
[`error_chain!`]: https://docs.rs/error-chain/*/error_chain/macro.error_chain.html
[`Error`]: https://doc.rust-lang.org/std/error/trait.Error.html
[`foreign_links`]: https://docs.rs/error-chain/*/error_chain/#foreign-links
[`std::io::Error`]: https://doc.rust-lang.org/std/io/struct.Error.html
[`thiserror`]: https://docs.rs/thiserror/latest/thiserror/

[handle errors in Rust]: https://doc.rust-lang.org/book/second-edition/ch09-00-error-handling.html
[`Box`ing errors]: https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/boxing_errors.html
[Designing error types in Rust]: https://mmapped.blog/posts/12-rust-error-handling
4 changes: 4 additions & 0 deletions rust-cookbook/src/links.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ Keep lines sorted.

[ansi_term-badge]: https://badge-cache.kominick.com/crates/v/ansi_term.svg?label=ansi_term
[ansi_term]: https://docs.rs/ansi_term/
[anyhow-badge]: https://badge-cache.kominick.com/crates/v/anyhow.svg?label=anyhow
[anyhow]: https://docs.rs/anyhow/
[base64-badge]: https://badge-cache.kominick.com/crates/v/base64.svg?label=base64
[base64]: https://docs.rs/base64/
[bitflags-badge]: https://badge-cache.kominick.com/crates/v/bitflags.svg?label=bitflags
Expand Down Expand Up @@ -135,6 +137,8 @@ Keep lines sorted.
[tar]: https://docs.rs/tar/
[tempfile-badge]: https://badge-cache.kominick.com/crates/v/tempfile.svg?label=tempfile
[tempfile]: https://docs.rs/tempfile/
[thiserror-badge]: https://badge-cache.kominick.com/crates/v/thiserror.svg?label=thiserror
[thiserror]: https://docs.rs/thiserror/
[threadpool-badge]: https://badge-cache.kominick.com/crates/v/threadpool.svg?label=threadpool
[threadpool]: https://docs.rs/threadpool/
[toml-badge]: https://badge-cache.kominick.com/crates/v/toml.svg?label=toml
Expand Down

0 comments on commit 9a56456

Please sign in to comment.