diff --git a/src/ch09-01-unrecoverable-errors-with-panic.md b/src/ch09-01-unrecoverable-errors-with-panic.md index 5c27c8f07f..2fc98835cd 100644 --- a/src/ch09-01-unrecoverable-errors-with-panic.md +++ b/src/ch09-01-unrecoverable-errors-with-panic.md @@ -31,12 +31,14 @@ panic occurs to make it easier to track down the source of the panic. Let’s try calling `panic!` in a simple program: -Filename: src/main.rs + ```rust,should_panic,panics {{#rustdoc_include ../listings/ch09-error-handling/no-listing-01-panic/src/main.rs}} ``` + + When you run the program, you’ll see something like this: ```console @@ -64,14 +66,13 @@ a `panic!` call comes from a library because of a bug in our code instead of from our code calling the macro directly. Listing 9-1 has some code that attempts to access an index in a vector beyond the range of valid indexes. -Filename: src/main.rs + ```rust,should_panic,panics {{#rustdoc_include ../listings/ch09-error-handling/listing-09-01/src/main.rs}} ``` -Listing 9-1: Attempting to access an element beyond the -end of a vector, which will cause a call to `panic!` + Here, we’re attempting to access the 100th element of our vector (which is at index 99 because indexing starts at zero), but the vector has only three @@ -117,6 +118,8 @@ copy the backtrace output below check the backtrace number mentioned in the text below the listing --> ++ ```console $ RUST_BACKTRACE=1 cargo run thread 'main' panicked at src/main.rs:4:6: @@ -141,8 +144,7 @@ stack backtrace: note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. ``` -Listing 9-2: The backtrace generated by a call to -`panic!` displayed when the environment variable `RUST_BACKTRACE` is set + That’s a lot of output! The exact output you see might be different depending on your operating system and Rust version. In order to get backtraces with this diff --git a/src/ch09-02-recoverable-errors-with-result.md b/src/ch09-02-recoverable-errors-with-result.md index 35bcd11474..9f3387c292 100644 --- a/src/ch09-02-recoverable-errors-with-result.md +++ b/src/ch09-02-recoverable-errors-with-result.md @@ -29,13 +29,13 @@ return may differ. Let’s call a function that returns a `Result` value because the function could fail. In Listing 9-3 we try to open a file. -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch09-error-handling/listing-09-03/src/main.rs}} ``` -Listing 9-3: Opening a file + The return type of `File::open` is a `Result`. The generic parameter `T` has been filled in by the implementation of `File::open` with the type of the @@ -59,14 +59,13 @@ on the value `File::open` returns. Listing 9-4 shows one way to handle the `Result` using a basic tool, the `match` expression that we discussed in Chapter 6. -Filename: src/main.rs + ```rust,should_panic {{#rustdoc_include ../listings/ch09-error-handling/listing-09-04/src/main.rs}} ``` -Listing 9-4: Using a `match` expression to handle the -`Result` variants that might be returned + Note that, like the `Option` enum, the `Result` enum and its variants have been brought into scope by the prelude, so we don’t need to specify `Result::` @@ -98,7 +97,7 @@ reason—for example, because we didn’t have permission to open the file—we want the code to `panic!` in the same way it did in Listing 9-4. For this, we add an inner `match` expression, shown in Listing 9-5. -Filename: src/main.rs + @@ -107,8 +106,7 @@ tests to fail lol --> {{#rustdoc_include ../listings/ch09-error-handling/listing-09-05/src/main.rs}} ``` -Listing 9-5: Handling different kinds of errors in -different ways + The type of the value that `File::open` returns inside the `Err` variant is `io::Error`, which is a struct provided by the standard library. This struct @@ -172,12 +170,14 @@ Listing 9-4. If the `Result` value is the `Ok` variant, `unwrap` will return the value inside the `Ok`. If the `Result` is the `Err` variant, `unwrap` will call the `panic!` macro for us. Here is an example of `unwrap` in action: -Filename: src/main.rs + ```rust,should_panic {{#rustdoc_include ../listings/ch09-error-handling/no-listing-04-unwrap/src/main.rs}} ``` + + If we run this code without a *hello.txt* file, we’ll see an error message from the `panic!` call that the `unwrap` method makes: @@ -197,12 +197,14 @@ Using `expect` instead of `unwrap` and providing good error messages can convey your intent and make tracking down the source of a panic easier. The syntax of `expect` looks like this: -Filename: src/main.rs + ```rust,should_panic {{#rustdoc_include ../listings/ch09-error-handling/no-listing-05-expect/src/main.rs}} ``` + + We use `expect` in the same way as `unwrap`: to return the file handle or call the `panic!` macro. The error message used by `expect` in its call to `panic!` will be the parameter that we pass to `expect`, rather than the default @@ -237,7 +239,7 @@ For example, Listing 9-6 shows a function that reads a username from a file. If the file doesn’t exist or can’t be read, this function will return those errors to the code that called the function. -Filename: src/main.rs + {{#include ../listings/ch09-error-handling/listing-09-06/src/main.rs:here}} ``` -Listing 9-6: A function that returns errors to the -calling code using `match` + This function can be written in a much shorter way, but we’re going to start by doing a lot of it manually in order to explore error handling; at the end, @@ -307,7 +308,7 @@ Listing 9-7 shows an implementation of `read_username_from_file` that has the same functionality as in Listing 9-6, but this implementation uses the `?` operator. -Filename: src/main.rs + {{#include ../listings/ch09-error-handling/listing-09-07/src/main.rs:here}} ``` -Listing 9-7: A function that returns errors to the -calling code using the `?` operator + The `?` placed after a `Result` value is defined to work in almost the same way as the `match` expressions we defined to handle the `Result` values in Listing @@ -355,7 +355,7 @@ The `?` operator eliminates a lot of boilerplate and makes this function’s implementation simpler. We could even shorten this code further by chaining method calls immediately after the `?`, as shown in Listing 9-8. -Filename: src/main.rs + {{#include ../listings/ch09-error-handling/listing-09-08/src/main.rs:here}} ``` -Listing 9-8: Chaining method calls after the `?` -operator + We’ve moved the creation of the new `String` in `username` to the beginning of the function; that part hasn’t changed. Instead of creating a variable @@ -379,7 +378,7 @@ this is just a different, more ergonomic way to write it. Listing 9-9 shows a way to make this even shorter using `fs::read_to_string`. -Filename: src/main.rs + {{#include ../listings/ch09-error-handling/listing-09-09/src/main.rs:here}} ``` -Listing 9-9: Using `fs::read_to_string` instead of -opening and then reading the file + Reading a file into a string is a fairly common operation, so the standard library provides the convenient `fs::read_to_string` function that opens the @@ -413,14 +411,13 @@ In Listing 9-10, let’s look at the error we’ll get if we use the `?` operato in a `main` function with a return type that is incompatible with the type of the value we use `?` on. -Filename: src/main.rs + ```rust,ignore,does_not_compile {{#rustdoc_include ../listings/ch09-error-handling/listing-09-10/src/main.rs}} ``` -Listing 9-10: Attempting to use the `?` in the `main` -function that returns `()` won’t compile. + This code opens a file, which might fail. The `?` operator follows the `Result` value returned by `File::open`, but this `main` function has the return type of @@ -451,12 +448,13 @@ resultant value of the expression, and the function continues. Listing 9-11 has an example of a function that finds the last character of the first line in the given text. ++ ```rust {{#rustdoc_include ../listings/ch09-error-handling/listing-09-11/src/main.rs:here}} ``` -Listing 9-11: Using the `?` operator on an `Option` -value + This function returns `Option` because it’s possible that there is a character there, but it’s also possible that there isn’t. This code takes the @@ -496,14 +494,13 @@ from Listing 9-10, but we’ve changed the return type of `main` to be `Result<(), Box>` and added a return value `Ok(())` to the end. This code will now compile. -Filename: src/main.rs + ```rust,ignore {{#rustdoc_include ../listings/ch09-error-handling/listing-09-12/src/main.rs}} ``` -Listing 9-12: Changing `main` to return `Result<(), E>` -allows the use of the `?` operator on `Result` values. + The `Box` type is a *trait object*, which we’ll talk about in the [“Using Trait Objects that Allow for Values of Different diff --git a/src/ch09-03-to-panic-or-not-to-panic.md b/src/ch09-03-to-panic-or-not-to-panic.md index 40f93d67ce..297db0f7ec 100644 --- a/src/ch09-03-to-panic-or-not-to-panic.md +++ b/src/ch09-03-to-panic-or-not-to-panic.md @@ -140,12 +140,14 @@ One way to do this would be to parse the guess as an `i32` instead of only a `u32` to allow potentially negative numbers, and then add a check for the number being in range, like so: -Filename: src/main.rs + ```rust,ignore {{#rustdoc_include ../listings/ch09-error-handling/no-listing-09-guess-out-of-range/src/main.rs:here}} ``` + + The `if` expression checks whether our value is out of range, tells the user about the problem, and calls `continue` to start the next iteration of the loop and ask for another guess. After the `if` expression, we can proceed with the @@ -164,14 +166,13 @@ confidently use the values they receive. Listing 9-13 shows one way to define a `Guess` type that will only create an instance of `Guess` if the `new` function receives a value between 1 and 100. -Filename: src/lib.rs + ```rust {{#rustdoc_include ../listings/ch09-error-handling/listing-09-13/src/lib.rs}} ``` -Listing 9-13: A `Guess` type that will only continue with -values between 1 and 100 + First we define a struct named `Guess` that has a field named `value` that holds an `i32`. This is where the number will be stored.