liveBook · Manning

Error type

As explained in Rust Servers, Services, and Apps

A custom error type is a programmer-defined Rust type that represents application-specific failures and can unify multiple underlying error types.

A custom error type gives a Rust function one error type to return when its operations can fail in different ways. For example, parsing a number can return ParseIntError, while opening or writing a file can return std::io::Error. A function declared to return only ParseIntError cannot propagate both with ?; an application-defined enum can represent both failures. section 5.2

For a web service, define the error enum in an errors.rs module. Give it variants for the failures handlers must distinguish, such as database, Actix, and not-found errors. Implement From for underlying error types so ? can propagate them as the custom type, then return that type from database-access functions and route handlers. section 5.3 section 5.7

Listing 5.1 Error handling: part 1
use actix_web::{error, http::StatusCode, HttpResponse, Result};
use serde::Serialize;
use sqlx::error::Error as SQLxError;
use std::fmt;
 
#[derive(Debug, Serialize)]
pub enum EzyTutorError {          #1
    DBError(String),
    ActixError(String),
    NotFound(String),
}
#[derive(Debug, Serialize)]
pub struct MyErrorResponse {      #2
    error_message: String,
}

The enum separates internal failure categories from the response structure that carries a client-facing error_message. section 5.3

Implement Actix Web’s ResponseError for the enum to turn returned errors into HTTP responses. Database and Actix errors map to HTTP 500; not-found errors map to HTTP 404. Build a JSON response with an appropriate message. The demonstrated mapping logs internal messages while returning shorter messages for server errors. section 5.3

Listing 5.3 Error handling: part 3
impl error::ResponseError for EzyTutorError {
    fn status_code(&self) -> StatusCode {               #1
        match self {
          EzyTutorError::DBError(msg) | EzyTutorError::ActixError(msg) => {
              StatusCode::INTERNAL_SERVER_ERROR
            }
          EzyTutorError::NotFound(msg) => StatusCode::NOT_FOUND,
        }
    }
    fn error_response(&self) -> HttpResponse {          #2
        HttpResponse::build(self.status_code()).json(MyErrorResponse {
          error_message: self.error_response(),
        })
    }
}

The ResponseError implementation supplies both the status code and the JSON response body. section 5.3

Propagate a course-insertion error

A database function returns Result<Course, EzyTutorError> and uses ? after the SQL insert. Its route handler returns Result<HttpResponse, EzyTutorError>, mapping a successful Course to an OK JSON response while leaving errors for Actix to convert. A handler test unwraps the successful result and checks for HTTP 200; the service can also be exercised with a POST request and cargo test. section 5.6

The same approach extends to a server-rendered registration application: its error enum adds a template-error variant alongside database, Actix, and not-found variants. Form-input errors can instead lead the handler to re-render the form with a suitable message. section 8.1 section 8.4

How Rust Servers, Services, and Apps covers it

How deep it goes
Works through enum variants, From conversions, ResponseError status and body methods, and handler return types.
Examples
Uses a parsing-and-file-I/O mismatch, a course-insertion handler, and a registration error enum.
What it assumes
Assumes familiarity with Rust functions and handlers while explaining Result propagation and the reason to unify error types.
What you can do after
Build it from scratch for an Actix service, propagate database failures, and return category-appropriate HTTP responses.
How it connects
Connects Result, the ? operator, From, ResponseError, HTTP status codes, and JSON responses.

Also explained in

Compare how 5 books explain error type →

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.