Skip to content

Commit 8e6d015

Browse files
committed
Revision: add some clarifications and naming alternatives
1 parent 6abf70a commit 8e6d015

File tree

1 file changed

+36
-6
lines changed

1 file changed

+36
-6
lines changed

active/0000-error-conventions.md

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,9 @@ An API may define a contract that goes beyond the type checking enforced by the
8282
compiler. For example, slices support an indexing operation, with the contract
8383
that the supplied index must be in bounds.
8484

85-
Contracts can be complex. For example, the `RefCell` type requires that
86-
`borrow_mut` not be called until all existing borrows have been relinquished.
85+
Contracts can be complex and involve more than a single function invocation. For
86+
example, the `RefCell` type requires that `borrow_mut` not be called until all
87+
existing borrows have been relinquished.
8788

8889
### For contract violations, fail the task.
8990

@@ -114,13 +115,22 @@ contracts. However, here are some rough guidelines:
114115
patterns where the client does not want to check inputs before hand, but would
115116
rather attempt the operation and then find out whether the inputs were invalid.
116117

118+
* When a contract violation is the *only* kind of error a function may encounter
119+
-- i.e., there are no obstructions to its success other than "bad" inputs --
120+
using `Result` or `Option` instead is especially warranted. Clients can then use
121+
`unwrap` to assert that they have passed valid input, or re-use the error
122+
checking done by the API for their own purposes.
123+
117124
* When in doubt, use loose contracts and instead return a `Result` or `Option`.
118125

119126
## Obstructions
120127

121128
An operation is *obstructed* if it cannot be completed for some reason, even
122-
though the operation's contract has been satisfied. Obstructed operations must
123-
still leave the relevant data structures in a coherent state.
129+
though the operation's contract has been satisfied. Obstructed operations may
130+
have (documented!) side effects -- they are not required to roll back after
131+
encountering an obstruction. However, they should leave the data structures in
132+
a "coherent" state (satisfying their invariants, continuing to guarantee safety,
133+
etc.).
124134

125135
Obstructions may involve external conditions (e.g., I/O), or they may involve
126136
aspects of the input that are not covered by the contract.
@@ -138,7 +148,8 @@ obstructions in a fine-grained way.
138148
If there are multiple ways an operation might be obstructed, or there is useful
139149
information about the obstruction (such as where in the input a parse error
140150
occurred), prefer to use `Result`. For operations with a single obvious
141-
obstruction (like popping from an empty stack), use `Option`.
151+
obstruction that can provide no additional information (e.g. popping from an
152+
empty stack), use `Option`.
142153

143154
(Currently, `Option` does not interact well with other error-handling
144155
infrastructure like `try!`, but this will likely be improved in the future.)
@@ -156,7 +167,7 @@ intended as assertions. If there is no other way to check in advance for the
156167
validity of invoking an operation `foo`, however, the API may provide a
157168
`foo_catch` variant that returns a `Result`.
158169

159-
The main examples in `libstd` providing both variants are:
170+
The main examples in `libstd` that *currently* provide both variants are:
160171

161172
* Channels, which are the primary point of failure propagation between tasks. As
162173
such, calling `recv()` is an _assertion_ that the other end of the channel is
@@ -177,6 +188,8 @@ The main examples in `libstd` providing both variants are:
177188
> Note: the `try_` prefix would be replaced by a `_catch` catch if this RFC is
178189
> accepted.
179190
191+
(Note: it is unclear whether these APIs will continue to provide both variants.)
192+
180193
# Drawbacks
181194

182195
The main drawbacks of this proposal are:
@@ -203,3 +216,20 @@ As was
203216
however, mixing what might be seen as contract violations with obstructions can
204217
make it much more difficult to write obstruction-robust code; see the linked
205218
comment for more detail.
219+
220+
## Naming
221+
222+
There are numerous possible suffixes for a `Result`-producing variant:
223+
224+
* `_catch`, as proposed above. As
225+
[@kballard points out](https://github.com/rust-lang/rfcs/pull/236#issuecomment-55344336),
226+
this name connotes exception handling, which could be considered
227+
misleading. However, since it effectively prevents further unwinding, catching
228+
an exception may indeed be the right analogy.
229+
230+
* `_result`, which is straightforward but not as informative/suggestive as some
231+
of the other proposed variants.
232+
233+
* `try_` prefix. Also connotes exception handling, but has an unfortunately
234+
overlap with the common use of `try_` for nonblocking variants (which is in
235+
play for `recv` in particular).

0 commit comments

Comments
 (0)