Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 7b5dce9

Browse files
committed
This is a pretty good start if you ask me
1 parent 72898ac commit 7b5dce9

File tree

2 files changed

+138
-67
lines changed

2 files changed

+138
-67
lines changed

library/core/src/result.rs

Lines changed: 6 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,79 +1024,19 @@ impl<T, E> Result<T, E> {
10241024
/// x.expect("Testing expect"); // panics with `Testing expect: emergency failure`
10251025
/// ```
10261026
///
1027-
/// # Common Message Styles
1027+
/// # Recommended Message Style
10281028
///
1029-
/// There are two common styles for how people word `expect` messages. Using
1030-
/// the message to present information to users encountering a panic
1031-
/// ("expect as error message") or using the message to present information
1032-
/// to developers debugging the panic ("expect as precondition").
1033-
///
1034-
/// In the former case the expect message is used to describe the error that
1035-
/// has occurred which is considered a bug. Consider the following example:
1036-
///
1037-
/// ```should_panic
1038-
/// // Read environment variable, panic if it is not present
1039-
/// let path = std::env::var("IMPORTANT_PATH").unwrap();
1040-
/// ```
1041-
///
1042-
/// In the "expect as error message" style we would use expect to describe
1043-
/// that the environment variable was not set when it should have been:
1044-
///
1045-
/// ```should_panic
1046-
/// let path = std::env::var("IMPORTANT_PATH")
1047-
/// .expect("env variable `IMPORTANT_PATH` is not set");
1048-
/// ```
1049-
///
1050-
/// In the "expect as precondition" style, we would instead describe the
1051-
/// reason we _expect_ the `Result` should be `Ok`. With this style we would
1052-
/// prefer to write:
1029+
/// We recommend that `expect` messages are used to describe the reason you
1030+
/// _expect_ the `Result` should be `Ok`.
10531031
///
10541032
/// ```should_panic
10551033
/// let path = std::env::var("IMPORTANT_PATH")
10561034
/// .expect("env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`");
10571035
/// ```
10581036
///
1059-
/// The "expect as error message" style does not work as well with the
1060-
/// default output of the std panic hooks, and often ends up repeating
1061-
/// information that is already communicated by the source error being
1062-
/// unwrapped:
1063-
///
1064-
/// ```text
1065-
/// thread 'main' panicked at 'env variable `IMPORTANT_PATH` is not set: NotPresent', src/main.rs:4:6
1066-
/// ```
1067-
///
1068-
/// In this example we end up mentioning that an env variable is not set,
1069-
/// followed by our source message that says the env is not present, the
1070-
/// only additional information we're communicating is the name of the
1071-
/// environment variable being checked.
1072-
///
1073-
/// The "expect as precondition" style instead focuses on source code
1074-
/// readability, making it easier to understand what must have gone wrong in
1075-
/// situations where panics are being used to represent bugs exclusively.
1076-
/// Also, by framing our expect in terms of what "SHOULD" have happened to
1077-
/// prevent the source error, we end up introducing new information that is
1078-
/// independent from our source error.
1079-
///
1080-
/// ```text
1081-
/// thread 'main' panicked at 'env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`: NotPresent', src/main.rs:4:6
1082-
/// ```
1083-
///
1084-
/// In this example we are communicating not only the name of the
1085-
/// environment variable that should have been set, but also an explanation
1086-
/// for why it should have been set, and we let the source error display as
1087-
/// a clear contradiction to our expectation.
1088-
///
1089-
/// For programs where panics may be user facing, either style works best
1090-
/// when paired with a custom [panic hook] like the one provided by the CLI
1091-
/// working group library, [`human-panic`]. This panic hook dumps the panic
1092-
/// messages to a crash report file while showing users a more friendly
1093-
/// "Oops, something went wrong!" message with a suggestion to send the
1094-
/// crash report file back to the developers. Panic messages should be used
1095-
/// to represent bugs, and the information provided back is context intended
1096-
/// for the developer, not the user.
1097-
///
1098-
/// [panic hook]: https://doc.rust-lang.org/stable/std/panic/fn.set_hook.html
1099-
/// [`human-panic`]: https://docs.rs/human-panic
1037+
/// For more detail on expect message styles and the reasoning behind our
1038+
/// recommendation please refer to the section on ["Common Message
1039+
/// Styles"]() in the [`std::error`]() module docs.
11001040
#[inline]
11011041
#[track_caller]
11021042
#[stable(feature = "result_expect", since = "1.4.0")]

library/std/src/error.rs

Lines changed: 132 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,135 @@
1-
//! Traits for working with Errors.
1+
//! Interfaces for working with Errors.
2+
//!
3+
//! # Error Handling In Rust
4+
//!
5+
//! The Rust language provides two complementary systems for constructing /
6+
//! representing, reporting, propagating, reacting to, and discarding errors.
7+
//! These responsibilities are collectively known as "error handling." The
8+
//! components of the first system, the panic runtime and interfaces, are most
9+
//! commonly used to represent bugs that have been detected in your program. The
10+
//! components of the second system, `Result`, the error traits, and user
11+
//! defined types, are used to represent anticipated runtime failure modes of
12+
//! your program.
13+
//!
14+
//! ## The Panic Interfaces
15+
//!
16+
//! The following are the primary interfaces of the panic system and the
17+
//! responsibilities they cover:
18+
//!
19+
//! * [`panic!`] and [`panic_any`] (Constructing, Propagated automatically)
20+
//! * [`PanicInfo`] (Reporting)
21+
//! * [`set_hook`], [`take_hook`], and [`#[panic_handler]`] (Reporting)
22+
//! * [`catch_unwind`] and [`resume_unwind`] (Discarding, Propagating)
23+
//!
24+
//! The following are the primary interfaces of the error system and the
25+
//! responsibilities they cover:
26+
//!
27+
//! * [`Result`] (Propagating, Reacting)
28+
//! * The [`Error`] trait (Reporting)
29+
//! * User defined types (Constructing / Representing)
30+
//! * `match` and [`downcast`] (Reacting)
31+
//! * The propagation operator (`?`) (Propagating)
32+
//! * The partially stable [`Try`] traits (Propagating, Constructing)
33+
//! * [`Termination`] (Reporting)
34+
//!
35+
//! ## Converting Errors into Panics
36+
//!
37+
//! The panic and error systems are not entirely distinct. Often times errors
38+
//! that are anticipated runtime failures in an API might instead represent bugs
39+
//! to a caller. For these situations the standard library provides APIs for
40+
//! constructing panics with an `Error` as it's source.
41+
//!
42+
//! * `Result::unwrap`
43+
//! * `Result::expect`
44+
//!
45+
//! TODO: how do I bridge these two sections?
46+
//!
47+
//! * unwrap is used in prototyping
48+
//! * expect is used in !prototyping (????)
49+
//!
50+
//! # Common Message Styles
51+
//!
52+
//! There are two common styles for how people word `expect` messages. Using
53+
//! the message to present information to users encountering a panic
54+
//! ("expect as error message") or using the message to present information
55+
//! to developers debugging the panic ("expect as precondition").
56+
//!
57+
//! In the former case the expect message is used to describe the error that
58+
//! has occurred which is considered a bug. Consider the following example:
59+
//!
60+
//! ```should_panic
61+
//! // Read environment variable, panic if it is not present
62+
//! let path = std::env::var("IMPORTANT_PATH").unwrap();
63+
//! ```
64+
//!
65+
//! In the "expect as error message" style we would use expect to describe
66+
//! that the environment variable was not set when it should have been:
67+
//!
68+
//! ```should_panic
69+
//! let path = std::env::var("IMPORTANT_PATH")
70+
//! .expect("env variable `IMPORTANT_PATH` is not set");
71+
//! ```
72+
//!
73+
//! In the "expect as precondition" style, we would instead describe the
74+
//! reason we _expect_ the `Result` should be `Ok`. With this style we would
75+
//! prefer to write:
76+
//!
77+
//! ```should_panic
78+
//! let path = std::env::var("IMPORTANT_PATH")
79+
//! .expect("env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`");
80+
//! ```
81+
//!
82+
//! The "expect as error message" style does not work as well with the
83+
//! default output of the std panic hooks, and often ends up repeating
84+
//! information that is already communicated by the source error being
85+
//! unwrapped:
86+
//!
87+
//! ```text
88+
//! thread 'main' panicked at 'env variable `IMPORTANT_PATH` is not set: NotPresent', src/main.rs:4:6
89+
//! ```
90+
//!
91+
//! In this example we end up mentioning that an env variable is not set,
92+
//! followed by our source message that says the env is not present, the
93+
//! only additional information we're communicating is the name of the
94+
//! environment variable being checked.
95+
//!
96+
//! The "expect as precondition" style instead focuses on source code
97+
//! readability, making it easier to understand what must have gone wrong in
98+
//! situations where panics are being used to represent bugs exclusively.
99+
//! Also, by framing our expect in terms of what "SHOULD" have happened to
100+
//! prevent the source error, we end up introducing new information that is
101+
//! independent from our source error.
102+
//!
103+
//! ```text
104+
//! thread 'main' panicked at 'env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`: NotPresent', src/main.rs:4:6
105+
//! ```
106+
//!
107+
//! In this example we are communicating not only the name of the
108+
//! environment variable that should have been set, but also an explanation
109+
//! for why it should have been set, and we let the source error display as
110+
//! a clear contradiction to our expectation.
111+
//!
112+
//! For programs where panics may be user facing, either style works best
113+
//! when paired with a custom [panic hook] like the one provided by the CLI
114+
//! working group library, [`human-panic`]. This panic hook dumps the panic
115+
//! messages to a crash report file while showing users a more friendly
116+
//! "Oops, something went wrong!" message with a suggestion to send the
117+
//! crash report file back to the developers. Panic messages should be used
118+
//! to represent bugs, and the information provided back is context intended
119+
//! for the developer, not the user.
120+
//!
121+
//! [panic hook]: crate::panic::set_hook
122+
//! [`set_hook`]: crate::panic::set_hook
123+
//! [`take_hook`]: crate::panic::take_hook
124+
//! [`PanicInfo`]: crate::panic::PanicInfo
125+
//! [`panic_any`]: crate::panic::panic_any
126+
//! [`#[panic_handler]`]: https://doc.rust-lang.org/nomicon/panic-handler.html
127+
//! [`catch_unwind`]: crate::panic::catch_unwind
128+
//! [`resume_unwind`]: crate::panic::resume_unwind
129+
//! [`Termination`]: crate::process::Termination
130+
//! [`Try`]: crate::ops::Try
131+
//! [`downcast`]: crate::error::Error
132+
//! [`human-panic`]: https://docs.rs/human-panic
2133
3134
#![stable(feature = "rust1", since = "1.0.0")]
4135

0 commit comments

Comments
 (0)