Skip to content

Commit

Permalink
Clarifications.
Browse files Browse the repository at this point in the history
  • Loading branch information
aturon committed Oct 27, 2014
1 parent 8e6d015 commit aee1de5
Showing 1 changed file with 22 additions and 16 deletions.
38 changes: 22 additions & 16 deletions active/0000-error-conventions.md → text/0000-error-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ but it tries to motivate and clarify them.

Errors fall into one of three categories:

* Catastrophic errors, e.g. out of memory.
* Catastrophic errors, e.g. out-of-memory.
* Contract violations, e.g. wrong input encoding, index out of bounds.
* Obstructions, e.g. file not found, parse error.

Expand All @@ -67,14 +67,11 @@ Catastrophic errors are _extremely_ rare, especially outside of `libstd`.

**Canonical examples**: out of memory, stack overflow.

### For catastrophic errors, abort the process or fail the task.
### For catastrophic errors, fail the task.

For errors like out-of-memory, even correctly unwinding is impossible (since it
may require allocation); the process is aborted.

For errors like stack overflow, Rust currently aborts the process, but could in
principle fail the task, which would allow reporting and recovery from a
supervisory task.
For errors like stack overflow, Rust currently aborts the process, but
could in principle fail the task, which (in the best case) would allow
reporting and recovery from a supervisory task.

## Contract violations

Expand Down Expand Up @@ -137,22 +134,31 @@ aspects of the input that are not covered by the contract.

**Canonical examples**: file not found, parse error.

### For obstructions, use `Result` (or `Option`).
### For obstructions, use `Result`

The
[`Result<T,E>` type](http://static.rust-lang.org/doc/master/std/result/index.html)
represents either a success (yielding `T`) or failure (yielding `E`). By
returning a `Result`, a function allows its clients to discover and react to
obstructions in a fine-grained way.

If there are multiple ways an operation might be obstructed, or there is useful
information about the obstruction (such as where in the input a parse error
occurred), prefer to use `Result`. For operations with a single obvious
obstruction that can provide no additional information (e.g. popping from an
empty stack), use `Option`.
#### What about `Option`?

The `Option` type should not be used for "obstructed" operations; it
should only be used when a `None` return value could be considered a
"successful" execution of the operation.

This is of course a somewhat subjective question, but a good litmus
test is: would a reasonable client ever ignore the result? The
`Result` type provides a lint that ensures the result is actually
inspected, while `Option` does not, and this difference of behavior
can help when deciding between the two types.

(Currently, `Option` does not interact well with other error-handling
infrastructure like `try!`, but this will likely be improved in the future.)
Another litmus test: can the operation be understood as asking a
question (possibly with sideeffects)? Operations like `pop` on a
vector can be viewed as asking for the contents of the first element,
with the side effect of removing it if it exists -- with an `Option`
return value.

## Do not provide both `Result` and `fail!` variants.

Expand Down

0 comments on commit aee1de5

Please sign in to comment.