0
0
Rustprogramming~20 mins

Custom error types in Rust - Practice Problems & Coding Challenges

Choose your learning style9 modes available
Challenge - 5 Problems
🎖️
Rust Custom Error Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
Predict Output
intermediate
2:00remaining
What is the output of this Rust code with a custom error?

Look at this Rust code that defines a custom error and uses it in a function. What will it print?

Rust
use std::fmt;

#[derive(Debug)]
struct MyError {
    details: String,
}

impl fmt::Display for MyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Error: {}", self.details)
    }
}

impl std::error::Error for MyError {}

fn might_fail(fail: bool) -> Result<&'static str, MyError> {
    if fail {
        Err(MyError { details: String::from("Something went wrong") })
    } else {
        Ok("Success")
    }
}

fn main() {
    match might_fail(true) {
        Ok(msg) => println!("{}", msg),
        Err(e) => println!("{}", e),
    }
}
Apanic occurred: Something went wrong
BError: Something went wrong
CSuccess
DCompilation error due to missing trait implementation
Attempts:
2 left
💡 Hint

Check what the Err variant prints using the Display trait.

Predict Output
intermediate
2:00remaining
What does this Rust code print when no error occurs?

This code uses a custom error type but calls the function with false. What is printed?

Rust
use std::fmt;

#[derive(Debug)]
struct MyError {
    details: String,
}

impl fmt::Display for MyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Error: {}", self.details)
    }
}

impl std::error::Error for MyError {}

fn might_fail(fail: bool) -> Result<&'static str, MyError> {
    if fail {
        Err(MyError { details: String::from("Something went wrong") })
    } else {
        Ok("Success")
    }
}

fn main() {
    match might_fail(false) {
        Ok(msg) => println!("{}", msg),
        Err(e) => println!("{}", e),
    }
}
ASuccess
BError: Something went wrong
Cpanic occurred: Something went wrong
DCompilation error due to missing trait implementation
Attempts:
2 left
💡 Hint

Look at the Ok branch of the match.

Predict Output
advanced
2:00remaining
What error does this Rust code raise?

This code tries to create a custom error but forgets to implement a trait. What error occurs?

Rust
struct MyError {
    details: String,
}

fn main() {
    let err = MyError { details: String::from("Oops") };
    println!("{}", err);
}
ANo error, prints: Oops
Berror[E0382]: use of moved value: `err`
Cerror[E0277]: `MyError` doesn't implement `std::fmt::Display`
Derror[E0425]: cannot find value `err` in this scope
Attempts:
2 left
💡 Hint

Printing with {} requires the Display trait.

🧠 Conceptual
advanced
2:00remaining
Which statement about custom error types in Rust is true?

Choose the correct statement about creating and using custom error types in Rust.

ACustom error types must implement the <code>std::error::Error</code> trait to be used with <code>Result</code>.
BImplementing <code>std::fmt::Display</code> is optional for custom error types.
CCustom error types can only hold string data and nothing else.
DYou cannot use <code>match</code> to handle custom error types.
Attempts:
2 left
💡 Hint

Think about what traits Rust expects for error handling.

Predict Output
expert
3:00remaining
What is the output of this Rust code with nested custom errors?

This Rust code defines two custom error types and nests one inside the other. What will it print?

Rust
use std::fmt;

#[derive(Debug)]
struct InnerError {
    msg: String,
}

impl fmt::Display for InnerError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Inner error: {}", self.msg)
    }
}

impl std::error::Error for InnerError {}

#[derive(Debug)]
struct OuterError {
    source: InnerError,
}

impl fmt::Display for OuterError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Outer error caused by: {}", self.source)
    }
}

impl std::error::Error for OuterError {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        Some(&self.source)
    }
}

fn main() {
    let inner = InnerError { msg: String::from("disk failure") };
    let outer = OuterError { source: inner };
    println!("{}", outer);
}
ACompilation error due to missing lifetime annotations
BInner error: disk failure
COuter error caused by: disk failure
DOuter error caused by: Inner error: disk failure
Attempts:
2 left
💡 Hint

Look at how Display is implemented for OuterError.