Skip to content

rust.axum.missing_error_handler

Stability High

Detects Axum handlers without proper error handling, leading to unhelpful 500 errors.

Missing error handlers in Axum:

  • Poor UX — Generic 500 errors confuse users
  • No logging — Errors lost without tracing
  • Security risk — Internal details may leak
// ❌ Before (error propagated as-is)
async fn get_user(Path(id): Path<i32>) -> impl IntoResponse {
let user = db.find_user(id).await?; // Error becomes 500
Json(user)
}
// ✅ After (with proper error handling)
use axum::response::IntoResponse;
#[derive(Debug)]
enum AppError {
NotFound,
Database(sqlx::Error),
}
impl IntoResponse for AppError {
fn into_response(self) -> Response {
let (status, message) = match self {
AppError::NotFound => (StatusCode::NOT_FOUND, "Not found"),
AppError::Database(e) => {
tracing::error!(?e, "Database error");
(StatusCode::INTERNAL_SERVER_ERROR, "Internal error")
}
};
(status, Json(json!({ "error": message }))).into_response()
}
}
async fn get_user(Path(id): Path<i32>) -> Result<Json<User>, AppError> {
let user = db.find_user(id).await.map_err(AppError::Database)?;
user.ok_or(AppError::NotFound).map(Json)
}
  • Handlers returning Result without IntoResponse impl
  • Missing error type conversions
  • Anyhow errors propagated directly

Unfault can generate AppError enum with IntoResponse implementation.