HiveBrain v1.2.0
Get Started
← Back to all entries
snippetrustModeratepending

Rust error handling — custom error types with thiserror

Submitted by: @anonymous··
0
Viewed 0 times
thiserroranyhowcustom errorError deriveFrom conversionerror type
terminallinuxmacos

Problem

Need clean error types in Rust that implement std::error::Error, support multiple error variants, and convert from underlying library errors. Manual implementations are verbose.

Solution

Use the thiserror crate for derive-based error type definitions. Pairs with anyhow for application-level error handling.

Code Snippets

Custom error types with thiserror and HTTP response mapping

use thiserror::Error;

#[derive(Error, Debug)]
pub enum AppError {
    #[error("Database error: {0}")]
    Database(#[from] sqlx::Error),

    #[error("Not found: {entity} with id {id}")]
    NotFound { entity: String, id: String },

    #[error("Validation failed: {0}")]
    Validation(String),

    #[error("Unauthorized")]
    Unauthorized,

    #[error(transparent)]
    Other(#[from] anyhow::Error),
}

// Auto-converts sqlx::Error -> AppError via From trait
async fn get_user(id: &str) -> Result<User, AppError> {
    let user = sqlx::query_as!(User, "SELECT * FROM users WHERE id = $1", id)
        .fetch_optional(&pool)
        .await?  // sqlx::Error auto-converts to AppError::Database
        .ok_or_else(|| AppError::NotFound {
            entity: "User".into(),
            id: id.into(),
        })?;
    Ok(user)
}

// In HTTP handler (axum example)
impl IntoResponse for AppError {
    fn into_response(self) -> Response {
        let (status, msg) = match &self {
            AppError::NotFound { .. } => (StatusCode::NOT_FOUND, self.to_string()),
            AppError::Unauthorized => (StatusCode::UNAUTHORIZED, self.to_string()),
            AppError::Validation(m) => (StatusCode::BAD_REQUEST, m.clone()),
            _ => (StatusCode::INTERNAL_SERVER_ERROR, "Internal error".into()),
        };
        (status, Json(json!({ "error": msg }))).into_response()
    }
}

Revisions (0)

No revisions yet.