snippetrustModeratepending
Rust error handling — custom error types with thiserror
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.