Skip to content

Commit 4d20369

Browse files
committed
Auto merge of #28371 - killercup:docs/trpl-markup-fixes, r=steveklabnik
- Headlines begin at 1st level now like the rest of the book - All Headlines a blank line above and below - Fix links in this chapter's TOC r? @steveklabnik
2 parents b858f21 + 39f97cf commit 4d20369

File tree

1 file changed

+39
-36
lines changed

1 file changed

+39
-36
lines changed

src/doc/trpl/error-handling.md

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ When done naïvely, error handling in Rust can be verbose and annoying. This
1414
chapter will explore those stumbling blocks and demonstrate how to use the
1515
standard library to make error handling concise and ergonomic.
1616

17-
## Table of Contents
17+
# Table of Contents
1818

1919
This chapter is very long, mostly because we start at the very beginning with
2020
sum types and combinators, and try to motivate the way Rust does error handling
@@ -24,11 +24,11 @@ systems may want to jump around.
2424
* [The Basics](#the-basics)
2525
* [Unwrapping explained](#unwrapping-explained)
2626
* [The `Option` type](#the-option-type)
27-
* [Composing `Option<T>` values](#composing-option-t-values)
27+
* [Composing `Option<T>` values](#composing-optiont-values)
2828
* [The `Result` type](#the-result-type)
2929
* [Parsing integers](#parsing-integers)
3030
* [The `Result` type alias idiom](#the-result-type-alias-idiom)
31-
* [A brief interlude: unwrapping isn't evil](#a-brief-interlude-unwrapping-isn-t-evil)
31+
* [A brief interlude: unwrapping isn't evil](#a-brief-interlude-unwrapping-isnt-evil)
3232
* [Working with multiple error types](#working-with-multiple-error-types)
3333
* [Composing `Option` and `Result`](#composing-option-and-result)
3434
* [The limits of combinators](#the-limits-of-combinators)
@@ -42,17 +42,16 @@ systems may want to jump around.
4242
* [Composing custom error types](#composing-custom-error-types)
4343
* [Advice for library writers](#advice-for-library-writers)
4444
* [Case study: A program to read population data](#case-study-a-program-to-read-population-data)
45-
* [It's on Github](#it-s-on-github)
4645
* [Initial setup](#initial-setup)
4746
* [Argument parsing](#argument-parsing)
4847
* [Writing the logic](#writing-the-logic)
49-
* [Error handling with `Box<Error>`](#error-handling-with-box-error)
48+
* [Error handling with `Box<Error>`](#error-handling-with-boxerror)
5049
* [Reading from stdin](#reading-from-stdin)
5150
* [Error handling with a custom type](#error-handling-with-a-custom-type)
5251
* [Adding functionality](#adding-functionality)
5352
* [The short story](#the-short-story)
5453

55-
## The Basics
54+
# The Basics
5655

5756
You can think of error handling as using *case analysis* to determine whether
5857
a computation was successful or not. As you will see, the key to ergonomic error
@@ -107,7 +106,7 @@ You can think of this style of error handling as similar to a bull running
107106
through a china shop. The bull will get to where it wants to go, but it will
108107
trample everything in the process.
109108

110-
### Unwrapping explained
109+
## Unwrapping explained
111110

112111
In the previous example, we claimed
113112
that the program would simply panic if it reached one of the two error
@@ -121,7 +120,7 @@ It would be better if we just showed the code for unwrapping because it is so
121120
simple, but to do that, we will first need to explore the `Option` and `Result`
122121
types. Both of these types have a method called `unwrap` defined on them.
123122

124-
### The `Option` type
123+
## The `Option` type
125124

126125
The `Option` type is
127126
[defined in the standard library][1]:
@@ -205,7 +204,7 @@ The `unwrap` method *abstracts away the case analysis*. This is precisely the th
205204
that makes `unwrap` ergonomic to use. Unfortunately, that `panic!` means that
206205
`unwrap` is not composable: it is the bull in the china shop.
207206

208-
#### Composing `Option<T>` values
207+
### Composing `Option<T>` values
209208

210209
In [`option-ex-string-find`](#code-option-ex-string-find-2)
211210
we saw how to use `find` to discover the extension in a file name. Of course,
@@ -382,7 +381,8 @@ Combinators make using types like `Option` ergonomic because they reduce
382381
explicit case analysis. They are also composable because they permit the caller
383382
to handle the possibility of absence in their own way. Methods like `unwrap`
384383
remove choices because they will panic if `Option<T>` is `None`.
385-
### The `Result` type
384+
385+
## The `Result` type
386386

387387
The `Result` type is also
388388
[defined in the standard library][6]:
@@ -442,7 +442,7 @@ way to print a human readable description of values with that type.)
442442

443443
OK, let's move on to an example.
444444

445-
#### Parsing integers
445+
### Parsing integers
446446

447447
The Rust standard library makes converting strings to integers dead simple.
448448
It's so easy in fact, that it is very tempting to write something like the
@@ -548,7 +548,9 @@ Additionally, since `Result` has a second type parameter, there are
548548
combinators that affect only the error type, such as
549549
[`map_err`](../std/result/enum.Result.html#method.map_err) (instead of
550550
`map`) and [`or_else`](../std/result/enum.Result.html#method.or_else)
551-
(instead of `and_then`). #### The `Result` type alias idiom
551+
(instead of `and_then`).
552+
553+
### The `Result` type alias idiom
552554

553555
In the standard library, you may frequently see types like
554556
`Result<i32>`. But wait, [we defined `Result`](#code-result-def-1) to
@@ -580,9 +582,7 @@ module's type alias instead of the plain definition from
580582
`std::result`. (This idiom is also used for
581583
[`fmt::Result`](../std/fmt/type.Result.html).)
582584

583-
### A brief interlude:
584-
585-
unwrapping isn't evil
585+
## A brief interlude: unwrapping isn't evil
586586

587587
If you've been following along, you might have noticed that I've taken a pretty
588588
hard line against calling methods like `unwrap` that could `panic` and abort
@@ -620,7 +620,7 @@ Now that we've covered the basics of error handling in Rust, and
620620
explained unwrapping, let's start exploring more of the standard
621621
library.
622622

623-
## Working with multiple error types
623+
# Working with multiple error types
624624

625625
Thus far, we've looked at error handling where everything was either an
626626
`Option<T>` or a `Result<T, SomeError>`. But what happens when you have both an
@@ -629,7 +629,7 @@ Thus far, we've looked at error handling where everything was either an
629629
challenge in front of us, and it will be the major theme throughout the rest of
630630
this chapter.
631631

632-
### Composing `Option` and `Result`
632+
## Composing `Option` and `Result`
633633

634634
So far, I've talked about combinators defined for `Option` and combinators
635635
defined for `Result`. We can use these combinators to compose results of
@@ -706,7 +706,7 @@ the same (because of our use of `and_then`). Since we chose to convert the
706706
`Option<String>` (from `argv.nth(1)`) to a `Result<String, String>`, we must
707707
also convert the `ParseIntError` from `arg.parse()` to a `String`.
708708

709-
### The limits of combinators
709+
## The limits of combinators
710710

711711
Doing IO and parsing input is a very common task, and it's one that I
712712
personally have done a lot of in Rust. Therefore, we will use (and continue to
@@ -839,7 +839,7 @@ With all of that said, the code is still hairy. Mastering use of combinators is
839839
important, but they have their limits. Let's try a different approach: early
840840
returns.
841841

842-
### Early returns
842+
## Early returns
843843

844844
I'd like to take the code from the previous section and rewrite it using *early
845845
returns*. Early returns let you exit the function early. We can't return early
@@ -886,7 +886,7 @@ ergonomic error handling is reducing explicit case analysis, yet we've reverted
886886
back to explicit case analysis here. It turns out, there are *multiple* ways to
887887
reduce explicit case analysis. Combinators aren't the only way.
888888

889-
### The `try!` macro
889+
## The `try!` macro
890890

891891
A cornerstone of error handling in Rust is the `try!` macro. The `try!` macro
892892
abstracts case analysis just like combinators, but unlike combinators, it also
@@ -939,7 +939,7 @@ The good news is that we will soon learn how to remove those `map_err` calls!
939939
The bad news is that we will need to learn a bit more about a couple important
940940
traits in the standard library before we can remove the `map_err` calls.
941941

942-
### Defining your own error type
942+
## Defining your own error type
943943

944944
Before we dive into some of the standard library error traits, I'd like to wrap
945945
up this section by removing the use of `String` as our error type in the
@@ -1033,14 +1033,16 @@ will do in a pinch, particularly if you're writing an application. If you're
10331033
writing a library, defining your own error type should be strongly preferred so
10341034
that you don't remove choices from the caller unnecessarily.
10351035

1036-
## Standard library traits used for error handling
1036+
# Standard library traits used for error handling
10371037

10381038
The standard library defines two integral traits for error handling:
10391039
[`std::error::Error`](../std/error/trait.Error.html) and
10401040
[`std::convert::From`](../std/convert/trait.From.html). While `Error`
10411041
is designed specifically for generically describing errors, the `From`
10421042
trait serves a more general role for converting values between two
1043-
distinct types. ### The `Error` trait
1043+
distinct types.
1044+
1045+
## The `Error` trait
10441046

10451047
The `Error` trait is [defined in the standard
10461048
library](../std/error/trait.Error.html):
@@ -1147,7 +1149,7 @@ We note that this is a very typical implementation of `Error`: match on your
11471149
different error types and satisfy the contracts defined for `description` and
11481150
`cause`.
11491151

1150-
### The `From` trait
1152+
## The `From` trait
11511153

11521154
The `std::convert::From` trait is
11531155
[defined in the standard
@@ -1217,7 +1219,7 @@ us a way to reliably convert errors to the same type using the same function.
12171219

12181220
Time to revisit an old friend; the `try!` macro.
12191221

1220-
### The real `try!` macro
1222+
## The real `try!` macro
12211223

12221224
Previously, we presented this definition of `try!`:
12231225

@@ -1307,7 +1309,7 @@ chapter](https://crates.io/crates/error).)
13071309

13081310
It's time to revisit our custom `CliError` type and tie everything together.
13091311

1310-
### Composing custom error types
1312+
## Composing custom error types
13111313

13121314
In the last section, we looked at the real `try!` macro and how it does
13131315
automatic type conversion for us by calling `From::from` on the error value.
@@ -1437,7 +1439,7 @@ impl From<num::ParseFloatError> for CliError {
14371439

14381440
And that's it!
14391441

1440-
### Advice for library writers
1442+
## Advice for library writers
14411443

14421444
If your library needs to report custom errors, then you should
14431445
probably define your own error type. It's up to you whether or not to
@@ -1468,7 +1470,7 @@ library defines a single error type. This is used in the standard library
14681470
for [`io::Result`](../std/io/type.Result.html)
14691471
and [`fmt::Result`](../std/fmt/type.Result.html).
14701472

1471-
## Case study: A program to read population data
1473+
# Case study: A program to read population data
14721474

14731475
This chapter was long, and depending on your background, it might be
14741476
rather dense. While there is plenty of example code to go along with
@@ -1492,7 +1494,7 @@ parse the program arguments and decode that stuff into Rust types automatically.
14921494
[`csv`](https://crates.io/crates/csv),
14931495
and [`rustc-serialize`](https://crates.io/crates/rustc-serialize) crates.
14941496

1495-
### Initial setup
1497+
## Initial setup
14961498

14971499
We're not going to spend a lot of time on setting up a project with
14981500
Cargo because it is already covered well in [the Cargo
@@ -1524,7 +1526,7 @@ cargo build --release
15241526
# Outputs: Hello, world!
15251527
```
15261528

1527-
### Argument parsing
1529+
## Argument parsing
15281530

15291531
Let's get argument parsing out of the way. we won't go into too much
15301532
detail on Getopts, but there is [some good documentation][15]
@@ -1584,7 +1586,7 @@ print for the program name and template. If the user has not passed in
15841586
the help flag, we assign the proper variables to their corresponding
15851587
arguments.
15861588

1587-
### Writing the logic
1589+
## Writing the logic
15881590

15891591
We're all different in how we write code, but error handling is
15901592
usually the last thing we want to think about. This isn't very good
@@ -1681,7 +1683,7 @@ explore two different ways to approach handling these errors.
16811683
I'd like to start with `Box<Error>`. Later, we'll see how defining our own
16821684
error type can be useful.
16831685

1684-
### Error handling with `Box<Error>`
1686+
## Error handling with `Box<Error>`
16851687

16861688
`Box<Error>` is nice because it *just works*. You don't need to define your own
16871689
error types and you don't need any `From` implementations. The downside is that
@@ -1830,7 +1832,7 @@ Now that we've seen how to do proper error handling with `Box<Error>`, let's
18301832
try a different approach with our own custom error type. But first, let's take
18311833
a quick break from error handling and add support for reading from `stdin`.
18321834

1833-
### Reading from stdin
1835+
## Reading from stdin
18341836

18351837
In our program, we accept a single file for input and do one pass over the
18361838
data. This means we probably should be able to accept input on stdin. But maybe
@@ -1907,7 +1909,8 @@ fn search<P: AsRef<Path>>
19071909
// The rest remains unchanged!
19081910
}
19091911
```
1910-
### Error handling with a custom type
1912+
1913+
## Error handling with a custom type
19111914

19121915
Previously, we learned how to
19131916
[compose errors using a custom error type](#composing-custom-error-types).
@@ -2013,7 +2016,7 @@ fn search<P: AsRef<Path>>
20132016

20142017
No other changes are necessary.
20152018

2016-
### Adding functionality
2019+
## Adding functionality
20172020

20182021
Writing generic code is great, because generalizing stuff is cool, and
20192022
it can then be useful later. But sometimes, the juice isn't worth the
@@ -2073,7 +2076,7 @@ This pretty much sums up our case study. From here, you should be ready to go
20732076
out into the world and write your own programs and libraries with proper error
20742077
handling.
20752078

2076-
## The Short Story
2079+
# The Short Story
20772080

20782081
Since this chapter is long, it is useful to have a quick summary for error
20792082
handling in Rust. These are some good “rules of thumb." They are emphatically

0 commit comments

Comments
 (0)