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}