CodeBlanks Logo Icon CodeBlanks

Error trait

Define your own error by implementing std::error::Error.

The Error trait

std::error::Error is the common interface of error types. For a type to count as an error, it must implement Debug and Display; Error's methods have default bodies:

use std::error::Error;
use std::fmt;

#[derive(Debug)]
struct YasHatasi(i32);

impl fmt::Display for YasHatasi {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "geçersiz yaş: {}", self.0)
    }
}

impl Error for YasHatasi {}

Display is the message for the user; Debug is developer detail.

Returning with Box<dyn Error>

Your own error type can be converted into Box<dyn Error>; thanks to Display, it prints with {}:

fn yas(n: i32) -> Result<u8, Box<dyn Error>> {
    if !(0..=150).contains(&n) {
        return Err(Box::new(YasHatasi(n)));
    }
    Ok(n as u8)
}

match yas(-5) {
    Ok(y) => println!("{y}"),
    Err(e) => println!("{e}"),   // geçersiz yaş: -5
}

Practice Age check

Write the YasHatasi type above (Debug, Display, Error) and the yas function. Print the result of yas(30) with {:?} and the error of yas(-5) with {} on separate lines.

Starter code

main.rs
use std::error::Error;
use std::fmt;

fn main() {
    // buraya yaz
}

Sample solution

main.rs
use std::error::Error;
use std::fmt;

#[derive(Debug)]
struct YasHatasi(i32);

impl fmt::Display for YasHatasi {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "geçersiz yaş: {}", self.0)
    }
}

impl Error for YasHatasi {}

fn yas(n: i32) -> Result<u8, Box<dyn Error>> {
    if !(0..=150).contains(&n) {
        return Err(Box::new(YasHatasi(n)));
    }
    Ok(n as u8)
}

fn main() {
    println!("{:?}", yas(30).ok());
    if let Err(e) = yas(-5) {
        println!("{}", e);
    }
}

Expected output

Some(30)
geçersiz yaş: -5

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What is the advantage of the <code>Box&lt;dyn Error&gt;</code> return type?

  • It's faster
  • Distinguishing error kinds with match gets easier
  • It doesn't panic
  • It can return any type implementing Error via ? Correct answer

Explanation: You gain flexibility but lose the concrete type; if the caller wants to act by type it needs a downcast.

2 Implement Error

Question
impl ____ for YasHatasi {}
Answer
impl Error for YasHatasi {}

Explanation: If Display and Debug are in place, Error is implemented with an empty impl.

3 Trait and role

Term Meaning
Display User message
Debug Developer detail
Error Common error interface
Box<dyn Error> Any error

All lessons in Intermediate