Skip to content

Commit aa1ef53

Browse files
committed
Extended Try RFC
1 parent cb807b3 commit aa1ef53

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

active/0000-extended-try.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
- Start Date: 2014-06-25
2+
- RFC PR:
3+
- Rust Issue:
4+
5+
# Summary
6+
7+
Extend the `try!` macro to include an optional second parameter that is a constructor to wrap
8+
around the original error in case of failure.
9+
10+
# Motivation
11+
12+
`try!` is a useful macro when dealing with many functions that return `Result`s, but they become
13+
useless when the `Result` type that the programmer wants to return has a different failure type.
14+
For example, in a function that uses Io and Regex, two different error types could be generated
15+
(IoError, and Regex::Error). The author could not choose either of these errors to return because
16+
neither is extendable with the other. Instead it is common for library and application authors
17+
to create their own error types that wrap the errors that could possibly be produced. Unfortunately,
18+
this means that the `try!` macro is no longer useful.
19+
20+
# Detailed design
21+
22+
This RFC proposes adding another argument to the `try!` macro that would be used as a constructor
23+
to wrap around existing error types. For example:
24+
25+
```rust
26+
enum MyError {
27+
IoFailed(IoError),
28+
RegexFailed(regex::Error)
29+
}
30+
31+
fn read_then_regex(filename: &str, regex: &str) -> MyError {
32+
let file = try!(File::open(filename), IoFailed);
33+
let regex = try!(Regex::new(regex), RegexFailed);
34+
// do things
35+
}
36+
37+
```
38+
39+
The desugared version of this example (which is required to implement this pattern today)
40+
would look like:
41+
42+
```rust
43+
fn read_then_regex(filename: &str, regex: &str) -> MyError {
44+
let file = match File::open(filename) {
45+
Ok(a) => a,
46+
Err(x) => IoFailed(x)
47+
};
48+
let regex = match Regex::new(regex) {
49+
Ok(a) => a,
50+
Err(x) => RegexFailed(x)
51+
};
52+
// do things
53+
}
54+
```
55+
56+
The motivation for this improvement is the exact same as the motivation for the original `try!`
57+
macro.
58+
59+
The original form of the `try!` macro would still be valid and would continue to work without
60+
any changes.
61+
62+
# Drawbacks
63+
64+
Adds confusion. It is not immediately obvious as to what the 2nd argument is for if
65+
the reader is not already familiar with it.
66+
67+
# Alternatives
68+
69+
* Create another macro that is very similar
70+
* (named `try_or!` ?).
71+
* Create another macro that is very similar and place it in an external library

0 commit comments

Comments
 (0)