Prefer Result Type over try-catch
Context
In various programming languages, managing errors through exceptions, try-catch
, or throws
can obfuscate a function's behavior, making the code less predictable and harder to comprehend, as it's unclear whether, or what kind of, an exception will be thrown.
Opinion
Given the context, we prefer using the Result
type over try-catch
or throws
for error handling. Result
types clearly indicate a function's outcome and encapsulate the value or error, enhancing code predictability and readability.
How to Implement
use thiserror::Error;
// Example of a function that never throws an error
fn get_user() -> Result<(), UserError> {
Err(UserError::NotFound)
}
#[derive(Error, Debug)]
pub enum UserError {
#[error("User not found")]
NotFound,
}
// Other example of a function that never throws an error
fn get_api() -> Result<(), ApiError> {
Err(ApiError::BadResponse)
}
#[derive(Error, Debug)]
pub enum ApiError {
#[error("Bad response")]
BadResponse,
}
// Program
fn main() -> Result<(), ProgramError> {
get_user().map_err(ProgramError::User)?;
get_api().map_err(ProgramError::Api)?;
Ok(())
}
// Union of errors
pub enum ProgramError {
User(UserError),
Api(ApiError),
}