]>
Commit | Line | Data |
---|---|---|
94b46f34 XL |
1 | # Use the `Error` type |
2 | ||
3 | This pattern is a way to manage errors when you have multiple kinds of failure | |
4 | that could occur during a single function. It has several distinct advantages: | |
5 | ||
6 | 1. You can start using it without defining any of your own failure types. | |
7 | 2. All types that implement `Fail` can be thrown into the `Error` type using | |
8 | the `?` operator. | |
9 | 3. As you start adding new dependencies with their own failure types, you can | |
10 | start throwing them without making a breaking change. | |
11 | ||
12 | To use this pattern, all you need to do is return `Result<_, Error>` from your | |
13 | functions: | |
14 | ||
15 | ```rust | |
16 | use std::io; | |
17 | use std::io::BufRead; | |
18 | ||
19 | use failure::Error; | |
20 | use failure::err_msg; | |
21 | ||
22 | fn my_function() -> Result<(), Error> { | |
23 | let stdin = io::stdin(); | |
24 | ||
25 | for line in stdin.lock().lines() { | |
26 | let line = line?; | |
27 | ||
28 | if line.chars().all(|c| c.is_whitespace()) { | |
29 | break | |
30 | } | |
31 | ||
32 | if !line.starts_with("$") { | |
33 | return Err(format_err!("Input did not begin with `$`")); | |
34 | } | |
35 | ||
36 | println!("{}", &line[1..]); | |
37 | } | |
38 | ||
39 | Ok(()) | |
40 | } | |
41 | ``` | |
42 | ||
43 | ## When might you use this pattern? | |
44 | ||
45 | This pattern is very effective when you know you will usually not need to | |
46 | destructure the error this function returns. For example: | |
47 | ||
48 | - When prototyping. | |
49 | - When you know you are going to log this error, or display it to the user, | |
50 | either all of the time or nearly all of the time. | |
51 | - When it would be impractical for this API to report more custom context for | |
52 | the error (e.g. because it is a trait that doesn't want to add a new Error | |
53 | associated type). | |
54 | ||
55 | ## Caveats on this pattern | |
56 | ||
57 | There are two primary downsides to this pattern: | |
58 | ||
59 | - The `Error` type allocates. There are cases where this would be too | |
60 | expensive. In those cases you should use a [custom failure][custom-fail]. | |
61 | - You cannot recover more information about this error without downcasting. If | |
62 | your API needs to express more contextual information about the error, use | |
63 | the [Error and ErrorKind][error-errorkind] pattern. | |
64 | ||
65 | [custom-fail]: ./custom-fail.html | |
66 | [error-errorkind]: ./error-errorkind.html |