diff options
| author | Jane Lusby <jlusby@yaah.dev> | 2022-05-06 15:03:25 -0700 |
|---|---|---|
| committer | Jane Lusby <jlusby@yaah.dev> | 2022-05-06 15:03:25 -0700 |
| commit | 7b5dce900d6e5e8f8823720a3746441928eecb23 (patch) | |
| tree | 5ca7db8925003ff37d983e7b01ec7e48b47a2e63 /library/std/src | |
| parent | 72898acdba32e2ccc3fd1bc6deced97a8e1ad001 (diff) | |
| download | rust-7b5dce900d6e5e8f8823720a3746441928eecb23.tar.gz rust-7b5dce900d6e5e8f8823720a3746441928eecb23.zip | |
This is a pretty good start if you ask me
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/error.rs | 133 |
1 files changed, 132 insertions, 1 deletions
diff --git a/library/std/src/error.rs b/library/std/src/error.rs index 4fb94908c80..84089075f24 100644 --- a/library/std/src/error.rs +++ b/library/std/src/error.rs @@ -1,4 +1,135 @@ -//! Traits for working with Errors. +//! Interfaces for working with Errors. +//! +//! # Error Handling In Rust +//! +//! The Rust language provides two complementary systems for constructing / +//! representing, reporting, propagating, reacting to, and discarding errors. +//! These responsibilities are collectively known as "error handling." The +//! components of the first system, the panic runtime and interfaces, are most +//! commonly used to represent bugs that have been detected in your program. The +//! components of the second system, `Result`, the error traits, and user +//! defined types, are used to represent anticipated runtime failure modes of +//! your program. +//! +//! ## The Panic Interfaces +//! +//! The following are the primary interfaces of the panic system and the +//! responsibilities they cover: +//! +//! * [`panic!`] and [`panic_any`] (Constructing, Propagated automatically) +//! * [`PanicInfo`] (Reporting) +//! * [`set_hook`], [`take_hook`], and [`#[panic_handler]`] (Reporting) +//! * [`catch_unwind`] and [`resume_unwind`] (Discarding, Propagating) +//! +//! The following are the primary interfaces of the error system and the +//! responsibilities they cover: +//! +//! * [`Result`] (Propagating, Reacting) +//! * The [`Error`] trait (Reporting) +//! * User defined types (Constructing / Representing) +//! * `match` and [`downcast`] (Reacting) +//! * The propagation operator (`?`) (Propagating) +//! * The partially stable [`Try`] traits (Propagating, Constructing) +//! * [`Termination`] (Reporting) +//! +//! ## Converting Errors into Panics +//! +//! The panic and error systems are not entirely distinct. Often times errors +//! that are anticipated runtime failures in an API might instead represent bugs +//! to a caller. For these situations the standard library provides APIs for +//! constructing panics with an `Error` as it's source. +//! +//! * `Result::unwrap` +//! * `Result::expect` +//! +//! TODO: how do I bridge these two sections? +//! +//! * unwrap is used in prototyping +//! * expect is used in !prototyping (????) +//! +//! # Common Message Styles +//! +//! There are two common styles for how people word `expect` messages. Using +//! the message to present information to users encountering a panic +//! ("expect as error message") or using the message to present information +//! to developers debugging the panic ("expect as precondition"). +//! +//! In the former case the expect message is used to describe the error that +//! has occurred which is considered a bug. Consider the following example: +//! +//! ```should_panic +//! // Read environment variable, panic if it is not present +//! let path = std::env::var("IMPORTANT_PATH").unwrap(); +//! ``` +//! +//! In the "expect as error message" style we would use expect to describe +//! that the environment variable was not set when it should have been: +//! +//! ```should_panic +//! let path = std::env::var("IMPORTANT_PATH") +//! .expect("env variable `IMPORTANT_PATH` is not set"); +//! ``` +//! +//! In the "expect as precondition" style, we would instead describe the +//! reason we _expect_ the `Result` should be `Ok`. With this style we would +//! prefer to write: +//! +//! ```should_panic +//! let path = std::env::var("IMPORTANT_PATH") +//! .expect("env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`"); +//! ``` +//! +//! The "expect as error message" style does not work as well with the +//! default output of the std panic hooks, and often ends up repeating +//! information that is already communicated by the source error being +//! unwrapped: +//! +//! ```text +//! thread 'main' panicked at 'env variable `IMPORTANT_PATH` is not set: NotPresent', src/main.rs:4:6 +//! ``` +//! +//! In this example we end up mentioning that an env variable is not set, +//! followed by our source message that says the env is not present, the +//! only additional information we're communicating is the name of the +//! environment variable being checked. +//! +//! The "expect as precondition" style instead focuses on source code +//! readability, making it easier to understand what must have gone wrong in +//! situations where panics are being used to represent bugs exclusively. +//! Also, by framing our expect in terms of what "SHOULD" have happened to +//! prevent the source error, we end up introducing new information that is +//! independent from our source error. +//! +//! ```text +//! thread 'main' panicked at 'env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`: NotPresent', src/main.rs:4:6 +//! ``` +//! +//! In this example we are communicating not only the name of the +//! environment variable that should have been set, but also an explanation +//! for why it should have been set, and we let the source error display as +//! a clear contradiction to our expectation. +//! +//! For programs where panics may be user facing, either style works best +//! when paired with a custom [panic hook] like the one provided by the CLI +//! working group library, [`human-panic`]. This panic hook dumps the panic +//! messages to a crash report file while showing users a more friendly +//! "Oops, something went wrong!" message with a suggestion to send the +//! crash report file back to the developers. Panic messages should be used +//! to represent bugs, and the information provided back is context intended +//! for the developer, not the user. +//! +//! [panic hook]: crate::panic::set_hook +//! [`set_hook`]: crate::panic::set_hook +//! [`take_hook`]: crate::panic::take_hook +//! [`PanicInfo`]: crate::panic::PanicInfo +//! [`panic_any`]: crate::panic::panic_any +//! [`#[panic_handler]`]: https://doc.rust-lang.org/nomicon/panic-handler.html +//! [`catch_unwind`]: crate::panic::catch_unwind +//! [`resume_unwind`]: crate::panic::resume_unwind +//! [`Termination`]: crate::process::Termination +//! [`Try`]: crate::ops::Try +//! [`downcast`]: crate::error::Error +//! [`human-panic`]: https://docs.rs/human-panic #![stable(feature = "rust1", since = "1.0.0")] |
