liveBook · Manning

Unwrap

As explained in Rust Servers, Services, and Apps

unwrap is a Rust method that extracts a value from an Option or Result and panics if it is None or Err.

`unwrap()` extracts the success value from a Rust `Result<T, E>` and panics on an error. On an `Option`, it extracts the value when present and panics on `None`. It keeps early examples short, but turns a recoverable failure into a panic. section 2.2.2 section 5.4

A TCP echo server

In `tcpserver/src/main.rs`, `TcpListener::bind("127.0.0.1:3000").unwrap()` obtains a listener. The server also unwraps an incoming connection and the results of `read` and `write`. Any error at those points panics instead of being handled. section 2.2.2

For a web service, replace `unwrap()` on a fallible database fetch with `?` when the error should reach the calling handler. The database function must return a `Result`; its error can be converted to the service’s custom error type. The handler can then return that error for conversion into an HTTP response rather than letting a database error panic the thread. This change targets the fetch: the illustrated course-mapping code still calls `unwrap()` on a posted-time value. section 5.4 section 5.7

Listing 5.4 Error handling in the method to retrieve courses for a tutor
pub async fn get_courses_for_tutor_db(
    pool: &PgPool,
    tutor_id: i32,
) -> Result<Vec<Course>, EzyTutorError> {        #1
    // Prepare SQL statement
    let course_rows = sqlx::query!(
        "SELECT tutor_id, course_id, course_name,
        posted_time FROM ezy_course_c5 where tutor_id = $1",
        tutor_id
    )
    .fetch_all(pool)
    .await?;                                     #2
    // Extract result
 
    let courses: Vec<Course> = course_rows
        .iter()
        .map(|course_row| Course {
            course_id: course_row.course_id,
            tutor_id: course_row.tutor_id,
            course_name: course_row.course_name.clone(),
            posted_time: Some(chrono::NaiveDateTime::from(
            course_row.posted_time.unwrap())),
        })
        .collect();
    match courses.len() {                        #3
        0 => Err(EzyTutorError::NotFound(
            "Courses not found for tutor".into(),
        )),
        _ => Ok(courses),
    }
}

Compare `.fetch_all(pool).await?` with the remaining `posted_time.unwrap()` in the course-retrieval function. section 5.4

How Rust Servers, Services, and Apps covers it

How deep it goes
Defines success and panic behavior, then walks through replacing a database-fetch call; does not develop Option error handling.
Examples
Uses TCP listener and stream operations, a SQLx course query, and a remaining posted-time unwrap.
What it assumes
Assumes familiarity with Rust method calls while introducing Result<T, E> before applying it to database error propagation.
What you can do after
Apply it via Rust's unwrap() for short examples, and use ? to propagate database-fetch errors in a service.
How it connects
Connects unwrap to Result, Option, panic, the question mark operator, custom error types, and HTTP responses.

Also explained in

Compare how 5 books explain unwrap →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Rust Servers, Services, and Apps. The section links point to the parts of the book it draws on.