% Rust Condition and Error-handling Tutorial

# Introduction

Rust does not provide exception handling[^why-no-exceptions]
in the form most commonly seen in other programming languages such as C++ or Java.
Instead, it provides four mechanisms that work together to handle errors or other rare events.
The four mechanisms are:

  - Options
  - Results
  - Failure
  - Conditions

This tutorial will lead you through use of these mechanisms
in order to understand the trade-offs of each and relationships between them.

# Example program

This tutorial will be based around an example program
that attempts to read lines from a file
consisting of pairs of numbers,
and then print them back out with slightly different formatting.
The input to the program might look like this:

~~~~ {.notrust}
$ cat numbers.txt
1 2
34 56
789 123
45 67
~~~~

For which the intended output looks like this:

~~~~ {.notrust}
$ ./example numbers.txt
0001, 0002
0034, 0056
0789, 0123
0045, 0067
~~~~

An example program that does this task reads like this:

~~~~
# #[allow(unused_imports)];
extern mod extra;
use extra::fileinput::FileInput;
use std::int;
# mod FileInput {
#    use std::io::{Reader, BytesReader};
#    static s : &'static [u8] = bytes!("1 2\n\
#                                       34 56\n\
#                                       789 123\n\
#                                       45 67\n\
#                                       ");
#    pub fn from_args() -> @Reader{
#        @BytesReader {
#            bytes: s,
#            pos: @mut 0
#        } as @Reader
#    }
# }

fn main() {
    let pairs = read_int_pairs();
    for &(a,b) in pairs.iter() {
        println(fmt!("%4.4d, %4.4d", a, b));
    }
}


fn read_int_pairs() -> ~[(int,int)] {

    let mut pairs = ~[];

    let fi = FileInput::from_args();
    while ! fi.eof() {

        // 1. Read a line of input.
        let line = fi.read_line();

        // 2. Split the line into fields ("words").
        let fields = line.word_iter().to_owned_vec();

        // 3. Match the vector of fields against a vector pattern.
        match fields {

            // 4. When the line had two fields:
            [a, b] => {

                // 5. Try parsing both fields as ints.
                match (from_str::<int>(a), from_str::<int>(b)) {

                    // 6. If parsing succeeded for both, push both.
                    (Some(a), Some(b)) => pairs.push((a,b)),

                    // 7. Ignore non-int fields.
                    _ => ()
                }
            }

            // 8. Ignore lines that don't have 2 fields.
            _ => ()
        }
    }

    pairs
}
~~~~

This example shows the use of `Option`,
along with some other forms of error-handling (and non-handling).
We will look at these mechanisms
and then modify parts of the example to perform "better" error handling.


# Options

The simplest and most lightweight mechanism in Rust for indicating an error is the type `std::option::Option<T>`.
This type is a general purpose `enum`
for conveying a value of type `T`, represented as `Some(T)`
_or_ the sentinel `None`, to indicate the absence of a `T` value.
For simple APIs, it may be sufficient to encode errors as `Option<T>`,
returning `Some(T)` on success and `None` on error.
In the example program, the call to `from_str::<int>` returns `Option<int>`
with the understanding that "all parse errors" result in `None`.
The resulting `Option<int>` values are matched against the pattern `(Some(a), Some(b))`
in steps 5 and 6 in the example program,
to handle the case in which both fields were parsed successfully.

Using `Option` as in this API has some advantages:

  - Simple API, users can read it and guess how it works.
  - Very efficient, only an extra `enum` tag on return values.
  - Caller has flexibility in handling or propagating errors.
  - Caller is forced to acknowledge existence of possible-error before using value.

However, it has serious disadvantages too:

  - Verbose, requires matching results or calling `Option::unwrap` everywhere.
  - Infects caller: if caller doesn't know how to handle the error, must propagate (or force).
  - Temptation to do just that: force the `Some(T)` case by blindly calling `unwrap`,
    which hides the error from the API without providing any way to make the program robust against the error.
  - Collapses all errors into one:
    - Caller can't handle different errors differently.
    - Caller can't even report a very precise error message

Note that in order to keep the example code reasonably compact,
several unwanted cases are silently ignored:
lines that do not contain two fields, as well as fields that do not parse as ints.
To propagate these cases to the caller using `Option` would require even more verbose code.


# Results

Before getting into _trapping_ the error,
we will look at a slight refinement on the `Option` type above.
This second mechanism for indicating an error is called a `Result`.
The type `std::result::Result<T,E>` is another simple `enum` type with two forms, `Ok(T)` and `Err(E)`.
The `Result` type is not substantially different from the `Option` type in terms of its ergonomics.
Its main advantage is that the error constructor `Err(E)` can convey _more detail_ about the error.
For example, the `from_str` API could be reformed
to return a `Result` carrying an informative description of a parse error,
like this:

~~~~ {.ignore}
enum IntParseErr {
     EmptyInput,
     Overflow,
     BadChar(char)
}

fn from_str(&str) -> Result<int,IntParseErr> {
  // ...
}
~~~~

This would give the caller more information for both handling and reporting the error,
but would otherwise retain the verbosity problems of using `Option`.
In particular, it would still be necessary for the caller to return a further `Result` to _its_ caller if it did not want to handle the error.
Manually propagating result values this way can be attractive in certain circumstances
-- for example when processing must halt on the very first error, or backtrack --
but as we will see later, many cases have simpler options available.

# Failure

The third and arguably easiest mechanism for handling errors is called "failure".
In fact it was hinted at earlier by suggesting that one can choose to propagate `Option` or `Result` types _or "force" them_.
"Forcing" them, in this case, means calling a method like `Option<T>::unwrap`,
which contains the following code:

~~~~ {.ignore}
pub fn unwrap(self) -> T {
    match self {
      Some(x) => return x,
      None => fail!("option::unwrap `None`")
    }
}
~~~~

That is, it returns `T` when `self` is `Some(T)`, and  _fails_ when `self` is `None`.

Every Rust task can _fail_, either indirectly due to a kill signal or other asynchronous event,
or directly by failing an `assert!` or calling the `fail!` macro.
Failure is an _unrecoverable event_ at the task level:
it causes the task to halt normal execution and unwind its control stack,
freeing all task-local resources (the local heap as well as any task-owned values from the global heap)
and running destructors (the `drop` method of the `Drop` trait)
as frames are unwound and heap values destroyed.
A failing task is not permitted to "catch" the unwinding during failure and recover,
it is only allowed to clean up and exit.

Failure has advantages:

  - Simple and non-verbose. Suitable for programs that can't reasonably continue past an error anyways.
  - _All_ errors (except memory-safety errors) can be uniformly trapped in a supervisory task outside the failing task.
    For a large program to be robust against a variety of errors,
    often some form of task-level partitioning to contain pervasive errors (arithmetic overflow, division by zero,
    logic bugs) is necessary anyways.

As well as obvious disadvantages:

  - A blunt instrument, terminates the containing task entirely.

Recall that in the first two approaches to error handling,
the example program was only handling success cases, and ignoring error cases.
That is, if the input is changed to contain a malformed line:

~~~~ {.notrust}
$ cat bad.txt
1 2
34 56
ostrich
789 123
45 67
~~~~

Then the program would give the same output as if there was no error:

~~~~ {.notrust}
$ ./example bad.txt
0001, 0002
0034, 0056
0789, 0123
0045, 0067
~~~~

If the example is rewritten to use failure, these error cases can be trapped.
In this rewriting, failures are trapped by placing the I/O logic in a sub-task,
and trapping its exit status using `task::try`:

~~~~ {.xfail-test}
# #[allowed(unused_imports)];
extern mod extra;
use extra::fileinput::FileInput;
use std::int;
use std::task;
# mod FileInput {
#    use std::io::{Reader, BytesReader};
#    static s : &'static [u8] = bytes!("1 2\n\
#                                       34 56\n\
#                                       ostrich\n\
#                                       789 123\n\
#                                       45 67\n\
#                                       ");
#    pub fn from_args() -> @Reader{
#        @BytesReader {
#            bytes: s,
#            pos: @mut 0
#        } as @Reader
#    }
# }

fn main() {

    // Isolate failure within a subtask.
    let result = do task::try {

        // The protected logic.
        let pairs = read_int_pairs();
        for &(a,b) in pairs.iter() {
            println(fmt!("%4.4d, %4.4d", a, b));
        }

    };
    if result.is_err() {
            println("parsing failed");
    }
}

fn read_int_pairs() -> ~[(int,int)] {
    let mut pairs = ~[];
    let fi = FileInput::from_args();
    while ! fi.eof() {
        let line = fi.read_line();
        let fields = line.word_iter().to_owned_vec();
        match fields {
            [a, b] => pairs.push((from_str::<int>(a).unwrap(),
                                  from_str::<int>(b).unwrap())),

            // Explicitly fail on malformed lines.
            _ => fail!()
        }
    }
    pairs
}
~~~~

With these changes in place, running the program on malformed input gives a different answer:

~~~~ {.notrust}
$ ./example bad.txt
rust: task failed at 'explicit failure', ./example.rs:44
parsing failed
~~~~

Note that while failure unwinds the sub-task performing I/O in `read_int_pairs`,
control returns to `main` and can easily continue uninterrupted.
In this case, control simply prints out `parsing failed` and then exits `main` (successfully).
Failure of a (sub-)task is analogous to calling `exit(1)` or `abort()` in a unix C program:
all the state of a sub-task is cleanly discarded on exit,
and a supervisor task can take appropriate action
without worrying about its own state having been corrupted.


# Conditions

The final mechanism for handling errors is called a "condition".
Conditions are less blunt than failure, and less cumbersome than the `Option` or `Result` types;
indeed they are designed to strike just the right balance between the two.
Conditions require some care to use effectively, but give maximum flexibility with minimum verbosity.
While conditions use exception-like terminology ("trap", "raise") they are significantly different:

  - Like exceptions and failure, conditions separate the site at which the error is raised from the site where it is trapped.
  - Unlike exceptions and unlike failure, when a condition is raised and trapped, _no unwinding occurs_.
  - A successfully trapped condition causes execution to continue _at the site of the error_, as though no error occurred.

Conditions are declared with the `condition!` macro.
Each condition has a name, an input type and an output type, much like a function.
In fact, conditions are implemented as dynamically-scoped functions held in task local storage.

The `condition!` macro declares a module with the name of the condition;
the module contains a single static value called `cond`, of type `std::condition::Condition`.
The `cond` value within the module is the rendezvous point
between the site of error and the site that handles the error.
It has two methods of interest: `raise` and `trap`.

The `raise` method maps a value of the condition's input type to its output type.
The input type should therefore convey all relevant information to the condition handler.
The output type should convey all relevant information _for continuing execution at the site of error_.
When the error site raises a condition handler,
the `Condition::raise` method searches task-local storage (TLS) for the innermost installed _handler_,
and if any such handler is found, calls it with the provided input value.
If no handler is found, `Condition::raise` will fail the task with an appropriate error message.

Rewriting the example to use a condition in place of ignoring malformed lines makes it slightly longer,
but similarly clear as the version that used `fail!` in the logic where the error occurs:

~~~~ {.xfail-test}
# #[allow(unused_imports)];
extern mod extra;
use extra::fileinput::FileInput;
use std::int;
# mod FileInput {
#    use std::io::{Reader, BytesReader};
#    static s : &'static [u8] = bytes!("1 2\n\
#                                       34 56\n\
#                                       ostrich\n\
#                                       789 123\n\
#                                       45 67\n\
#                                       ");
#    pub fn from_args() -> @Reader{
#        @BytesReader {
#            bytes: s,
#            pos: @mut 0
#        } as @Reader
#    }
# }

// Introduce a new condition.
condition! {
    pub malformed_line : ~str -> (int,int);
}

fn main() {
    let pairs = read_int_pairs();
    for &(a,b) in pairs.iter() {
        println(fmt!("%4.4d, %4.4d", a, b));
    }
}

fn read_int_pairs() -> ~[(int,int)] {
    let mut pairs = ~[];
    let fi = FileInput::from_args();
    while ! fi.eof() {
        let line = fi.read_line();
        let fields = line.word_iter().to_owned_vec();
        match fields {
            [a, b] => pairs.push((from_str::<int>(a).unwrap(),
                                  from_str::<int>(b).unwrap())),

            // On malformed lines, call the condition handler and
            // push whatever the condition handler returns.
            _ => pairs.push(malformed_line::cond.raise(line.clone()))
        }
    }
    pairs
}
~~~~

When this is run on malformed input, it still fails,
but with a slightly different failure message than before:

~~~~ {.notrust}
$ ./example bad.txt
rust: task failed at 'Unhandled condition: malformed_line: ~"ostrich"', .../libstd/condition.rs:43
~~~~

While this superficially resembles the trapped `fail!` call before,
it is only because the example did not install a handler for the condition.
The different failure message is indicating, among other things,
that the condition-handling system is being invoked and failing
only due to the absence of a _handler_ that traps the condition.

# Trapping a condition

To trap a condition, use `Condition::trap` in some caller of the site that calls `Condition::raise`.
For example, this version of the program traps the `malformed_line` condition
and replaces bad input lines with the pair `(-1,-1)`:

~~~~
# #[allow(unused_imports)];
extern mod extra;
use extra::fileinput::FileInput;
use std::int;
# mod FileInput {
#    use std::io::{Reader, BytesReader};
#    static s : &'static [u8] = bytes!("1 2\n\
#                                       34 56\n\
#                                       ostrich\n\
#                                       789 123\n\
#                                       45 67\n\
#                                       ");
#    pub fn from_args() -> @Reader{
#        @BytesReader {
#            bytes: s,
#            pos: @mut 0
#        } as @Reader
#    }
# }

condition! {
    pub malformed_line : ~str -> (int,int);
}

fn main() {
    // Trap the condition:
    do malformed_line::cond.trap(|_| (-1,-1)).inside {

        // The protected logic.
        let pairs = read_int_pairs();
        for &(a,b) in pairs.iter() {
                println(fmt!("%4.4d, %4.4d", a, b));
        }

    }
}

fn read_int_pairs() -> ~[(int,int)] {
    let mut pairs = ~[];
    let fi = FileInput::from_args();
    while ! fi.eof() {
        let line = fi.read_line();
        let fields = line.word_iter().to_owned_vec();
        match fields {
            [a, b] => pairs.push((from_str::<int>(a).unwrap(),
                                  from_str::<int>(b).unwrap())),
            _ => pairs.push(malformed_line::cond.raise(line.clone()))
        }
    }
    pairs
}
~~~~

Note that the remainder of the program is _unchanged_ with this trap in place;
only the caller that installs the trap changed.
Yet when the condition-trapping variant runs on the malformed input,
it continues execution past the malformed line, substituting the handler's return value.

~~~~ {.notrust}
$ ./example bad.txt
0001, 0002
0034, 0056
-0001, -0001
0789, 0123
0045, 0067
~~~~

# Refining a condition

As you work with a condition, you may find that the original set of options you present for recovery is insufficient.
This is no different than any other issue of API design:
a condition handler is an API for recovering from the condition, and sometimes APIs need to be enriched.
In the example program, the first form of the `malformed_line` API implicitly assumes that recovery involves a substitute value.
This assumption may not be correct; some callers may wish to skip malformed lines, for example.
Changing the condition's return type from `(int,int)` to `Option<(int,int)>` will suffice to support this type of recovery:

~~~~
# #[allow(unused_imports)];
extern mod extra;
use extra::fileinput::FileInput;
use std::int;
# mod FileInput {
#    use std::io::{Reader, BytesReader};
#    static s : &'static [u8] = bytes!("1 2\n\
#                                       34 56\n\
#                                       ostrich\n\
#                                       789 123\n\
#                                       45 67\n\
#                                       ");
#    pub fn from_args() -> @Reader{
#        @BytesReader {
#            bytes: s,
#            pos: @mut 0
#        } as @Reader
#    }
# }

// Modify the condition signature to return an Option.
condition! {
    pub malformed_line : ~str -> Option<(int,int)>;
}

fn main() {
    // Trap the condition and return `None`
    do malformed_line::cond.trap(|_| None).inside {

        // The protected logic.
        let pairs = read_int_pairs();
        for &(a,b) in pairs.iter() {
            println(fmt!("%4.4d, %4.4d", a, b));
        }

    }
}

fn read_int_pairs() -> ~[(int,int)] {
    let mut pairs = ~[];
    let fi = FileInput::from_args();
    while ! fi.eof() {
        let line = fi.read_line();
        let fields = line.word_iter().to_owned_vec();
        match fields {
            [a, b] => pairs.push((from_str::<int>(a).unwrap(),
                                  from_str::<int>(b).unwrap())),

            // On malformed lines, call the condition handler and
            // either ignore the line (if the handler returns `None`)
            // or push any `Some(pair)` value returned instead.
            _ => {
                match malformed_line::cond.raise(line.clone()) {
                    Some(pair) => pairs.push(pair),
                    None => ()
                }
            }
        }
    }
    pairs
}
~~~~

Again, note that the remainder of the program is _unchanged_,
in particular the signature of `read_int_pairs` is unchanged,
even though the innermost part of its reading-loop has a new way of handling a malformed line.
When the example is run with the `None` trap in place,
the line is ignored as it was in the first example,
but the choice of whether to ignore or use a substitute value has been moved to some caller,
possibly a distant caller.

~~~~ {.notrust}
$ ./example bad.txt
0001, 0002
0034, 0056
0789, 0123
0045, 0067
~~~~

# Further refining a condition

Like with any API, the process of refining argument and return types of a condition will continue,
until all relevant combinations encountered in practice are encoded.
In the example, suppose a third possible recovery form arose: reusing the previous value read.
This can be encoded in the handler API by introducing a helper type: `enum MalformedLineFix`.

~~~~
# #[allow(unused_imports)];
extern mod extra;
use extra::fileinput::FileInput;
use std::int;
# mod FileInput {
#    use std::io::{Reader, BytesReader};
#    static s : &'static [u8] = bytes!("1 2\n\
#                                       34 56\n\
#                                       ostrich\n\
#                                       789 123\n\
#                                       45 67\n\
#                                       ");
#    pub fn from_args() -> @Reader{
#        @BytesReader {
#            bytes: s,
#            pos: @mut 0
#        } as @Reader
#    }
# }

// Introduce a new enum to convey condition-handling strategy to error site.
pub enum MalformedLineFix {
     UsePair(int,int),
     IgnoreLine,
     UsePreviousLine
}

// Modify the condition signature to return the new enum.
// Note: a condition introduces a new module, so the enum must be
// named with the `super::` prefix to access it.
condition! {
    pub malformed_line : ~str -> super::MalformedLineFix;
}

fn main() {
    // Trap the condition and return `UsePreviousLine`
    do malformed_line::cond.trap(|_| UsePreviousLine).inside {

        // The protected logic.
        let pairs = read_int_pairs();
        for &(a,b) in pairs.iter() {
            println(fmt!("%4.4d, %4.4d", a, b));
        }

    }
}

fn read_int_pairs() -> ~[(int,int)] {
    let mut pairs = ~[];
    let fi = FileInput::from_args();
    while ! fi.eof() {
        let line = fi.read_line();
        let fields = line.word_iter().to_owned_vec();
        match fields {
            [a, b] => pairs.push((from_str::<int>(a).unwrap(),
                                  from_str::<int>(b).unwrap())),

            // On malformed lines, call the condition handler and
            // take action appropriate to the enum value returned.
            _ => {
                match malformed_line::cond.raise(line.clone()) {
                    UsePair(a,b) => pairs.push((a,b)),
                    IgnoreLine => (),
                    UsePreviousLine => {
                        let prev = pairs[pairs.len() - 1];
                        pairs.push(prev)
                    }
                }
            }
        }
    }
    pairs
}
~~~~

Running the example with `UsePreviousLine` as the fix code returned from the handler
gives the expected result:

~~~~ {.notrust}
$ ./example bad.txt
0001, 0002
0034, 0056
0034, 0056
0789, 0123
0045, 0067
~~~~

At this point the example has a rich variety of recovery options,
none of which is visible to casual users of the `read_int_pairs` function.
This is intentional: part of the purpose of using a condition
is to free intermediate callers from the burden of having to write repetitive error-propagation logic,
and/or having to change function call and return types as error-handling strategies are refined.

# Multiple conditions, intermediate callers

So far the function trapping the condition and the function raising it have been immediately adjacent in the call stack.
That is, the caller traps and its immediate callee raises.
In most programs, the function that traps may be separated by very many function calls from the function that raises.
Again, this is part of the point of using conditions:
to support that separation without having to thread multiple error values and recovery strategies all the way through the program's main logic.

Careful readers will notice that there is a remaining failure mode in the example program: the call to `.unwrap()` when parsing each integer.
For example, when presented with a file that has the correct number of fields on a line,
but a non-numeric value in one of them, such as this:

~~~~ {.notrust}
$ cat bad.txt
1 2
34 56
7 marmot
789 123
45 67
~~~~


Then the program fails once more:

~~~~ {.notrust}
$ ./example bad.txt
task <unnamed> failed at 'called `Option::unwrap()` on a `None` value', .../libstd/option.rs:314
~~~~

To make the program robust -- or at least flexible -- in the face of this potential failure,
a second condition and a helper function will suffice:

~~~~
# #[allow(unused_imports)];
extern mod extra;
use extra::fileinput::FileInput;
use std::int;
# mod FileInput {
#    use std::io::{Reader, BytesReader};
#    static s : &'static [u8] = bytes!("1 2\n\
#                                       34 56\n\
#                                       7 marmot\n\
#                                       789 123\n\
#                                       45 67\n\
#                                       ");
#    pub fn from_args() -> @Reader{
#        @BytesReader {
#            bytes: s,
#            pos: @mut 0
#        } as @Reader
#    }
# }

pub enum MalformedLineFix {
     UsePair(int,int),
     IgnoreLine,
     UsePreviousLine
}

condition! {
    pub malformed_line : ~str -> ::MalformedLineFix;
}

// Introduce a second condition.
condition! {
    pub malformed_int : ~str -> int;
}

fn main() {
    // Trap the `malformed_int` condition and return -1
    do malformed_int::cond.trap(|_| -1).inside {

        // Trap the `malformed_line` condition and return `UsePreviousLine`
        do malformed_line::cond.trap(|_| UsePreviousLine).inside {

            // The protected logic.
            let pairs = read_int_pairs();
            for &(a,b) in pairs.iter() {
                println(fmt!("%4.4d, %4.4d", a, b));
            }

        }
    }
}

// Parse an int; if parsing fails, call the condition handler and
// return whatever it returns.
fn parse_int(x: &str) -> int {
    match from_str::<int>(x) {
        Some(v) => v,
        None => malformed_int::cond.raise(x.to_owned())
    }
}

fn read_int_pairs() -> ~[(int,int)] {
    let mut pairs = ~[];
    let fi = FileInput::from_args();
    while ! fi.eof() {
        let line = fi.read_line();
        let fields = line.word_iter().to_owned_vec();
        match fields {

            // Delegate parsing ints to helper function that will
            // handle parse errors by calling `malformed_int`.
            [a, b] => pairs.push((parse_int(a), parse_int(b))),

            _ => {
                match malformed_line::cond.raise(line.clone()) {
                    UsePair(a,b) => pairs.push((a,b)),
                    IgnoreLine => (),
                    UsePreviousLine => {
                        let prev = pairs[pairs.len() - 1];
                        pairs.push(prev)
                    }
                }
            }
        }
    }
    pairs
}
~~~~

Again, note that `read_int_pairs` has not changed signature,
nor has any of the machinery for trapping or raising `malformed_line`,
but now the program can handle the "right number of fields, non-integral field" form of bad input:

~~~~ {.notrust}
$ ./example bad.txt
0001, 0002
0034, 0056
0007, -0001
0789, 0123
0045, 0067
~~~~

There are three other things to note in this variant of the example program:

  - It traps multiple conditions simultaneously,
    nesting the protected logic of one `trap` call inside the other.

  - There is a function in between the `trap` site and `raise` site for the `malformed_int` condition.
    There could be any number of calls between them:
    so long as the `raise` occurs within a callee (of any depth) of the logic protected by the `trap` call,
    it will invoke the handler.

  - This variant insulates callers from a design choice in the library:
    the `from_str` function was designed to return an `Option<int>`,
    but this program insulates callers from that choice,
    routing all `None` values that arise from parsing integers in this file into the condition.


# When to use which technique

This tutorial explored several techniques for handling errors.
Each is appropriate to different circumstances:

  - If an error may be extremely frequent, expected, and very likely dealt with by an immediate caller,
    then returning an `Option` or `Result` type is best. These types force the caller to handle the error,
    and incur the lowest speed overhead, usually only returning one extra word to tag the return value.
    Between `Option` and `Result`: use an `Option` when there is only one kind of error,
    otherwise make an `enum FooErr` to represent the possible error codes and use `Result<T,FooErr>`.

  - If an error can reasonably be handled at the site it occurs by one of a few strategies -- possibly including failure --
    and it is not clear which strategy a caller would want to use, a condition is best.
    For many errors, the only reasonable "non-stop" recovery strategies are to retry some number of times,
    create or substitute an empty or sentinel value, ignore the error, or fail.

  - If an error cannot reasonably be handled at the site it occurs,
    and the only reasonable response is to abandon a large set of operations in progress,
    then directly failing is best.

Note that an unhandled condition will cause failure (along with a more-informative-than-usual message),
so if there is any possibility that a caller might wish to "ignore and keep going",
it is usually harmless to use a condition in place of a direct call to `fail!()`.


[^why-no-exceptions]: Exceptions in languages like C++ and Java permit unwinding, like Rust's failure system,
but with the option to halt unwinding partway through the process and continue execution.
This behavior unfortunately means that the _heap_ may be left in an inconsistent but accessible state,
if an exception is thrown part way through the process of initializing or modifying memory.
To compensate for this risk, correct C++ and Java code must program in an extremely elaborate and difficult "exception-safe" style
-- effectively transactional style against heap structures --
or else risk introducing silent and very difficult-to-debug errors due to control resuming in a corrupted heap after a caught exception.
These errors are frequently memory-safety errors, which Rust strives to eliminate,
and so Rust unwinding is unrecoverable within a single task:
once unwinding starts, the entire local heap of a task is destroyed and the task is terminated.
