Back to all reviewers

Design domain-specific error types

neondatabase/neon
Based on 8 comments
Rust

Create and use domain-specific error types instead of generic errors or anyhow. This improves error handling clarity and ensures proper error propagation through the codebase.

Error Handling Rust

Reviewer Prompt

Create and use domain-specific error types instead of generic errors or anyhow. This improves error handling clarity and ensures proper error propagation through the codebase.

Key guidelines:

  1. Define specific error types for your domain using enums
  2. Include variants for different failure modes (e.g., Cancelled, ShuttingDown)
  3. Provide clear, lowercase error messages with context
  4. Propagate errors using proper type mapping

Example:

// Instead of using anyhow or generic errors:
fn process() -> anyhow::Result<()> {
    if cancelled {
        bail!("operation cancelled"); // Generic error
    }
    Ok(())
}

// Create domain-specific error types:
#[derive(Error, Debug)]
pub enum ProcessError {
    #[error("operation cancelled")]
    Cancelled,
    #[error("failed to write to {path}: {source}")]
    IoError { path: String, source: std::io::Error },
    #[error("invalid configuration: {0}")]
    Config(String),
}

fn process() -> Result<(), ProcessError> {
    if cancelled {
        return Err(ProcessError::Cancelled);
    }
    Ok(())
}

// Proper error mapping when crossing domain boundaries:
fn handle_process() -> Result<(), ApiError> {
    process().map_err(|e| match e {
        ProcessError::Cancelled => ApiError::ServiceUnavailable,
        ProcessError::IoError { .. } => ApiError::InternalError,
        ProcessError::Config(_) => ApiError::BadRequest,
    })?;
    Ok(())
}
8
Comments Analyzed
Rust
Primary Language
Error Handling
Category

Source Discussions