1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
pub use std::error; pub use super::Error; /// A basic error triggered by something the user has done. /// /// Constructs a new [Error] describing a failure which was the result of an /// action that the user has taken. This error includes a description of what /// occurred, as well as some advice for the user to try to mitigate the problem. /// /// # Examples /// ``` /// use human_errors; /// /// human_errors::user( /// "We could not open the config file you provided.", /// "Make sure that the file exists and is readable by the application.", /// ); /// ``` pub fn user(description: &str, advice: &str) -> Error { Error::UserError(description.to_string(), advice.to_string(), None, None) } /// An error triggered by something the user has done, with a deeper cause. /// /// Constructs a new [Error] describing a failure which was the result of an /// action that the user has taken. This error includes a description of what /// occurred, as well as some advice for the user to try to mitigate the problem. /// It also includes the details of another error which resulted in this failure, /// as well as any advice that error may provide. /// /// # Examples /// ``` /// use human_errors; /// /// human_errors::user_with_cause( /// "We could not open the config file you provided.", /// "Make sure that you've specified a valid config file with the --config option.", /// human_errors::user( /// "We could not find a file at /home/user/.config/demo.yml", /// "Make sure that the file exists and is readable by the application." /// ) /// ); /// ``` pub fn user_with_cause(description: &str, advice: &str, cause: Error) -> Error { Error::UserError( description.to_string(), advice.to_string(), Some(Box::from(cause)), None, ) } /// An error triggered by something the user has done, with a deeper cause. /// /// Constructs a new [Error] describing a failure which was the result of an /// action that the user has taken. This error includes a description of what /// occurred, as well as some advice for the user to try to mitigate the problem. /// It also includes the details of another error which resulted in this failure. /// /// **NOTE**: The internal error may be any type which may be converted into a [Box<std::error::Error>]. /// /// # Examples /// ``` /// use human_errors; /// /// human_errors::user_with_internal( /// "We could not open the config file you provided.", /// "Make sure that the file exists and is readable by the application.", /// human_errors::detailed_message("ENOENT 2: No such file or directory") /// ); /// ``` pub fn user_with_internal<T>(description: &str, advice: &str, internal: T) -> Error where T: Into<Box<dyn error::Error + Send + Sync>>, { Error::UserError( description.to_string(), advice.to_string(), None, Some(internal.into()), ) } /// An error triggered by the system rather than the user. /// /// Constructs a new [Error] describing a failure which was the result of a failure /// in the system, rather than a user's action. This error includes a description of what /// occurred, as well as some advice for the user to try to mitigate the problem. /// /// # Examples /// ``` /// use human_errors; /// /// human_errors::system( /// "We could not open the config file you provided.", /// "Make sure that the file exists and is readable by the application." /// ); /// ``` pub fn system(description: &str, advice: &str) -> Error { Error::SystemError(description.to_string(), advice.to_string(), None, None) } /// An error triggered by the system rather than the user, with a deeper cause. /// /// Constructs a new [Error] describing a failure which was the result of a failure /// in the system, rather than a user's action. This error includes a description of what /// occurred, as well as some advice for the user to try to mitigate the problem. /// It also includes the details of another error which resulted in this failure, /// as well as any advice that error may provide. /// /// # Examples /// ``` /// use human_errors; /// /// human_errors::system_with_cause( /// "We could not open the config file you provided.", /// "Make sure that you've specified a valid config file with the --config option.", /// human_errors::system( /// "We could not find a file at /home/user/.config/demo.yml", /// "Make sure that the file exists and is readable by the application." /// ) /// ); /// ``` pub fn system_with_cause(description: &str, advice: &str, cause: Error) -> Error { Error::SystemError( description.to_string(), advice.to_string(), Some(Box::from(cause)), None, ) } /// An error triggered by the system rather than the user, with a deeper cause. /// /// Constructs a new [Error] describing a failure which was the result of a failure /// in the system, rather than a user's action. This error includes a description of what /// occurred, as well as some advice for the user to try to mitigate the problem. /// It also includes the details of another error which resulted in this failure. /// /// **NOTE**: The internal error may be any type which may be converted into a [Box<std::error::Error>]. /// /// # Examples /// ``` /// use human_errors; /// /// human_errors::system_with_internal( /// "We could not open the config file you provided.", /// "Make sure that the file exists and is readable by the application.", /// human_errors::detailed_message("ENOENT 2: No such file or directory") /// ); /// ``` pub fn system_with_internal<T>(description: &str, advice: &str, internal: T) -> Error where T: Into<Box<dyn error::Error + Send + Sync>>, { Error::SystemError( description.to_string(), advice.to_string(), None, Some(internal.into()), ) } #[cfg(test)] mod tests { use super::*; #[test] fn test_description() { assert_eq!( user( "Something bad happened", "Avoid bad things happening in future" ) .description(), "Something bad happened" ); assert_eq!( system( "Something bad happened", "Avoid bad things happening in future" ) .description(), "Something bad happened" ); } #[test] fn test_message_basic() { assert_eq!( user( "Something bad happened.", "Avoid bad things happening in future" ) .message(), "Oh no! Something bad happened.\n\nTo try and fix this, you can:\n - Avoid bad things happening in future" ); assert_eq!( system( "Something bad happened.", "Avoid bad things happening in future" ) .message(), "Whoops! Something bad happened. (This isn't your fault)\n\nTo try and fix this, you can:\n - Avoid bad things happening in future" ); } #[test] fn test_message_cause() { assert_eq!( user_with_cause( "Something bad happened.", "Avoid bad things happening in future", user("You got rate limited by GitHub.", "Wait a few minutes and try again.") ) .message(), "Oh no! Something bad happened.\n\nThis was caused by:\n - You got rate limited by GitHub.\n\nTo try and fix this, you can:\n - Wait a few minutes and try again.\n - Avoid bad things happening in future" ); assert_eq!( system_with_cause( "Something bad happened.", "Avoid bad things happening in future", system("You got rate limited by GitHub.", "Wait a few minutes and try again.") ) .message(), "Whoops! Something bad happened. (This isn't your fault)\n\nThis was caused by:\n - You got rate limited by GitHub.\n\nTo try and fix this, you can:\n - Wait a few minutes and try again.\n - Avoid bad things happening in future" ); } }