1Anyhow ¯\\\_(°ペ)\_/¯ 2========================== 3 4[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/anyhow-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/anyhow) 5[<img alt="crates.io" src="https://img.shields.io/crates/v/anyhow.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/anyhow) 6[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-anyhow-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/anyhow) 7[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/anyhow/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/anyhow/actions?query=branch%3Amaster) 8 9This library provides [`anyhow::Error`][Error], a trait object based error type 10for easy idiomatic error handling in Rust applications. 11 12[Error]: https://docs.rs/anyhow/1.0/anyhow/struct.Error.html 13 14```toml 15[dependencies] 16anyhow = "1.0" 17``` 18 19*Compiler support: requires rustc 1.34+* 20 21<br> 22 23## Details 24 25- Use `Result<T, anyhow::Error>`, or equivalently `anyhow::Result<T>`, as the 26 return type of any fallible function. 27 28 Within the function, use `?` to easily propagate any error that implements the 29 `std::error::Error` trait. 30 31 ```rust 32 use anyhow::Result; 33 34 fn get_cluster_info() -> Result<ClusterMap> { 35 let config = std::fs::read_to_string("cluster.json")?; 36 let map: ClusterMap = serde_json::from_str(&config)?; 37 Ok(map) 38 } 39 ``` 40 41- Attach context to help the person troubleshooting the error understand where 42 things went wrong. A low-level error like "No such file or directory" can be 43 annoying to debug without more context about what higher level step the 44 application was in the middle of. 45 46 ```rust 47 use anyhow::{Context, Result}; 48 49 fn main() -> Result<()> { 50 ... 51 it.detach().context("Failed to detach the important thing")?; 52 53 let content = std::fs::read(path) 54 .with_context(|| format!("Failed to read instrs from {}", path))?; 55 ... 56 } 57 ``` 58 59 ```console 60 Error: Failed to read instrs from ./path/to/instrs.json 61 62 Caused by: 63 No such file or directory (os error 2) 64 ``` 65 66- Downcasting is supported and can be by value, by shared reference, or by 67 mutable reference as needed. 68 69 ```rust 70 // If the error was caused by redaction, then return a 71 // tombstone instead of the content. 72 match root_cause.downcast_ref::<DataStoreError>() { 73 Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)), 74 None => Err(error), 75 } 76 ``` 77 78- If using the nightly channel, a backtrace is captured and printed with the 79 error if the underlying error type does not already provide its own. In order 80 to see backtraces, they must be enabled through the environment variables 81 described in [`std::backtrace`]: 82 83 - If you want panics and errors to both have backtraces, set 84 `RUST_BACKTRACE=1`; 85 - If you want only errors to have backtraces, set `RUST_LIB_BACKTRACE=1`; 86 - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and 87 `RUST_LIB_BACKTRACE=0`. 88 89 The tracking issue for this feature is [rust-lang/rust#53487]. 90 91 [`std::backtrace`]: https://doc.rust-lang.org/std/backtrace/index.html#environment-variables 92 [rust-lang/rust#53487]: https://github.com/rust-lang/rust/issues/53487 93 94- Anyhow works with any error type that has an impl of `std::error::Error`, 95 including ones defined in your crate. We do not bundle a `derive(Error)` macro 96 but you can write the impls yourself or use a standalone macro like 97 [thiserror]. 98 99 ```rust 100 use thiserror::Error; 101 102 #[derive(Error, Debug)] 103 pub enum FormatError { 104 #[error("Invalid header (expected {expected:?}, got {found:?})")] 105 InvalidHeader { 106 expected: String, 107 found: String, 108 }, 109 #[error("Missing attribute: {0}")] 110 MissingAttribute(String), 111 } 112 ``` 113 114- One-off error messages can be constructed using the `anyhow!` macro, which 115 supports string interpolation and produces an `anyhow::Error`. 116 117 ```rust 118 return Err(anyhow!("Missing attribute: {}", missing)); 119 ``` 120 121 A `bail!` macro is provided as a shorthand for the same early return. 122 123 ```rust 124 bail!("Missing attribute: {}", missing); 125 ``` 126 127<br> 128 129## No-std support 130 131In no_std mode, the same API is almost all available and works the same way. To 132depend on Anyhow in no_std mode, disable our default enabled "std" feature in 133Cargo.toml. A global allocator is required. 134 135```toml 136[dependencies] 137anyhow = { version = "1.0", default-features = false } 138``` 139 140Since the `?`-based error conversions would normally rely on the 141`std::error::Error` trait which is only available through std, no_std mode will 142require an explicit `.map_err(Error::msg)` when working with a non-Anyhow error 143type inside a function that returns Anyhow's error type. 144 145<br> 146 147## Comparison to failure 148 149The `anyhow::Error` type works something like `failure::Error`, but unlike 150failure ours is built around the standard library's `std::error::Error` trait 151rather than a separate trait `failure::Fail`. The standard library has adopted 152the necessary improvements for this to be possible as part of [RFC 2504]. 153 154[RFC 2504]: https://github.com/rust-lang/rfcs/blob/master/text/2504-fix-error.md 155 156<br> 157 158## Comparison to thiserror 159 160Use Anyhow if you don't care what error type your functions return, you just 161want it to be easy. This is common in application code. Use [thiserror] if you 162are a library that wants to design your own dedicated error type(s) so that on 163failures the caller gets exactly the information that you choose. 164 165[thiserror]: https://github.com/dtolnay/thiserror 166 167<br> 168 169#### License 170 171<sup> 172Licensed under either of <a href="LICENSE-APACHE">Apache License, Version 1732.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option. 174</sup> 175 176<br> 177 178<sub> 179Unless you explicitly state otherwise, any contribution intentionally submitted 180for inclusion in this crate by you, as defined in the Apache-2.0 license, shall 181be dual licensed as above, without any additional terms or conditions. 182</sub> 183