rust / intermediate
Snippet
Custom Error Types with Result<T, E>
Result<T, E> is Rust's primary error handling mechanism. By defining custom error enums, you can represent multiple failure modes with domain-specific information. Implementing the Display trait allows human-readable error messages. The From trait enables automatic error conversion with the ? operator, chaining operations that may fail. This approach composes well and makes error paths explicit in the type system.
snippet.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use std::fmt;use std::num::ParseIntError;#[derive(Debug)]enum ValidationError {EmptyString,TooShort { min: usize, actual: usize },ParseError(ParseIntError),OutOfRange { min: i32, max: i32, actual: i32 },}impl fmt::Display for ValidationError {fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {match self {ValidationError::EmptyString => write!(f, "String cannot be empty"),ValidationError::TooShort { min, actual } =>write!(f, "String too short: min={}, actual={}", min, actual),ValidationError::ParseError(e) => write!(f, "Parse error: {}", e),ValidationError::OutOfRange { min, max, actual } =>write!(f, "Value {} out of range [{}, {}]", actual, min, max),}}}impl From<ParseIntError> for ValidationError {fn from(err: ParseIntError) -> Self {ValidationError::ParseError(err)}}fn validate_age(input: &str) -> Result<i32, ValidationError> {if input.is_empty() {return Err(ValidationError::EmptyString);}if input.len() < 2 {return Err(ValidationError::TooShort { min: 2, actual: input.len() });}let age: i32 = input.parse()?;if age < 0 || age > 150 {return Err(ValidationError::OutOfRange { min: 0, max: 150, actual: age });}Ok(age)}fn main() {let test_cases = vec!["", "a", "25", "200", "-5"];for input in test_cases {match validate_age(input) {Ok(age) => println!("Valid age: {}", age),Err(e) => println!("Error for '{}': {}", input, e),}}}
Breakdown
1
enum ValidationError { ... }
Custom error enum with variants for different failure scenarios
2
impl fmt::Display for ValidationError
Implementing Display for user-facing error messages
3
impl From<ParseIntError> for ValidationError
From implementation enables ? operator to convert parse errors automatically
4
fn validate_age(input: &str) -> Result<i32, ValidationError>
Function returning Result type with custom error enum
5
let age: i32 = input.parse()?;
? operator propagates ParseIntError converted to ValidationError
6
match validate_age(input) { ... }
Match on Result to handle success and error cases explicitly