`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




