human_errors/
helpers.rs

1pub use super::{Error, Kind};
2use std::{borrow::Cow, error};
3
4/// An error triggered by something the user has done, with a deeper cause.
5///
6/// Constructs a new [Error] describing a failure which was the result of an
7/// action that the user has taken. This error includes a description of what
8/// occurred, as well as some advice for the user to try to mitigate the problem.
9/// It also includes the details of another error which resulted in this failure.
10///
11/// **NOTE**: The internal error may be any type which may be converted into a [Box<dyn error::Error>].
12///
13/// # Examples
14/// ```
15/// use human_errors;
16///
17/// human_errors::user(
18///   "ENOENT 2: No such file or directory",
19///   &["Make sure that the file exists and is readable by the application."],
20/// );
21/// ```
22pub fn user<T>(error: T, advice: &'static [&'static str]) -> Error
23where
24    T: Into<Box<dyn error::Error + Send + Sync>>,
25{
26    Error::new(error.into(), Kind::User, advice)
27}
28
29/// An error triggered by something the user has done, with a deeper cause.
30///
31/// Constructs a new [Error] describing a failure which was the result of an
32/// action that the user has taken. This error includes a description of what
33/// occurred, as well as some advice for the user to try to mitigate the problem.
34/// It also includes the details of another error which resulted in this failure.
35///
36/// **NOTE**: The internal error may be any type which may be converted into a [Box<dyn error::Error>].
37///
38/// # Examples
39/// ```
40/// use human_errors;
41///
42/// human_errors::wrap_user(
43///  human_errors::system("The configuration file was not found.", &["Make sure that the file exists and try again."]),
44///  "We could not open the config file you provided.",
45///  &["Make sure that the file exists and is readable by the application."],
46/// );
47/// ```
48pub fn wrap_user<
49    S: Into<Cow<'static, str>> + 'static,
50    E: Into<Box<dyn std::error::Error + Send + Sync + 'static>> + 'static,
51>(
52    inner: E,
53    message: S,
54    advice: &'static [&'static str],
55) -> Error {
56    Error::new(super::wrap(inner, message), Kind::User, advice)
57}
58
59/// An error triggered by the system rather than the user, with a deeper cause.
60///
61/// Constructs a new [Error] describing a failure which was the result of a failure
62/// in the system, rather than a user's action. This error includes a description of what
63/// occurred, as well as some advice for the user to try to mitigate the problem.
64/// It also includes the details of another error which resulted in this failure.
65///
66/// **NOTE**: The internal error may be any type which may be converted into a [Box<dyn error::Error>].
67///
68/// # Examples
69/// ```
70/// use human_errors;
71///
72/// human_errors::system(
73///   "ENOENT 2: No such file or directory",
74///   &["Make sure that the file exists and is readable by the application."],
75/// );
76/// ```
77pub fn system<T>(error: T, advice: &'static [&'static str]) -> Error
78where
79    T: Into<Box<dyn error::Error + Send + Sync>>,
80{
81    Error::new(error.into(), Kind::System, advice)
82}
83
84/// An error triggered by the system rather than the user, with a deeper cause.
85///
86/// Constructs a new [Error] describing a failure which was the result of a failure
87/// in the system, rather than a user's action. This error includes a description of what
88/// occurred, as well as some advice for the user to try to mitigate the problem.
89/// It also includes the details of another error which resulted in this failure.
90///
91/// **NOTE**: The internal error may be any type which may be converted into a [Box<dyn error::Error>].
92///
93/// # Examples
94/// ```
95/// use human_errors;
96/// human_errors::wrap_system(
97///  human_errors::user("The configuration file was not found.", &["Make sure that the file exists and try again."]),
98///  "We could not open the config file you provided.",
99///  &["Make sure that the file exists and is readable by the application."],
100/// );
101/// ```
102pub fn wrap_system<
103    S: Into<Cow<'static, str>> + 'static,
104    E: Into<Box<dyn std::error::Error + Send + Sync + 'static>> + 'static,
105>(
106    inner: E,
107    message: S,
108    advice: &'static [&'static str],
109) -> Error {
110    Error::new(super::wrap(inner, message), Kind::System, advice)
111}
112
113#[cfg(test)]
114mod tests {
115    use super::*;
116
117    #[test]
118    fn test_description() {
119        assert_eq!(
120            user(
121                "Something bad happened",
122                &["Avoid bad things happening in future"]
123            )
124            .description(),
125            "Something bad happened"
126        );
127
128        assert_eq!(
129            system(
130                "Something bad happened",
131                &["Avoid bad things happening in future"]
132            )
133            .description(),
134            "Something bad happened"
135        );
136    }
137
138    #[test]
139    fn test_message_basic() {
140        assert_eq!(
141            user(
142                "Something bad happened.",
143                &["Avoid bad things happening in future"]
144            )
145            .message(),
146            "Something bad happened. (User error)\n\nTo try and fix this, you can:\n - Avoid bad things happening in future"
147        );
148
149        assert_eq!(
150            system(
151                "Something bad happened.",
152                &["Avoid bad things happening in future"]
153            )
154            .message(),
155            "Something bad happened. (System failure)\n\nTo try and fix this, you can:\n - Avoid bad things happening in future"
156        );
157    }
158
159    #[test]
160    fn test_message_wrapped() {
161        assert_eq!(
162            wrap_user(
163                "You got rate limited",
164                "Something bad happened.",
165                &["Avoid bad things happening in future"]
166            )
167            .message(),
168            "Something bad happened. (User error)\n\nThis was caused by:\n - You got rate limited\n\nTo try and fix this, you can:\n - Avoid bad things happening in future"
169        );
170
171        assert_eq!(
172            wrap_system(
173                "You got rate limited",
174                "Something bad happened.",
175                &["Avoid bad things happening in future"]
176            )
177            .message(),
178            "Something bad happened. (System failure)\n\nThis was caused by:\n - You got rate limited\n\nTo try and fix this, you can:\n - Avoid bad things happening in future"
179        );
180    }
181}