about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorJane Lusby <jlusby@yaah.dev>2022-05-06 15:03:25 -0700
committerJane Lusby <jlusby@yaah.dev>2022-05-06 15:03:25 -0700
commit7b5dce900d6e5e8f8823720a3746441928eecb23 (patch)
tree5ca7db8925003ff37d983e7b01ec7e48b47a2e63 /library/std/src
parent72898acdba32e2ccc3fd1bc6deced97a8e1ad001 (diff)
downloadrust-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.rs133
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")]