rustlings 4

Published at 2024/09/07

Errors

It looks like in Rust, we can do some error handling by using a Result - essentially showing that we successfully ran a computation with Ok(T), or returning an error state with Err(String). The caller can then handle error cases appropriately, or choose to panic. I breezed through errors1 and errors2, and I learned that I can append a suffix of ? to calls that might result in errors, in order to have those errors immediately returned when they come up, in the Err side of the Result Enum.

Errors3

In this exercise, I arrived at an answer that compiles but left me unsatisfied:

fn main() {
    let mut tokens = 100;
    let pretend_user_input = "8";

    let cost = total_cost(pretend_user_input);

    let var_name = match cost  {
        Ok(cost_total) => cost_total,
        Err(error) => {
            return;
        }
    };
    let cost = var_name;

    if cost > tokens {
        println!("You can't afford that many!");
    } else {
        tokens -= cost;
        println!("You now have {} tokens.", tokens);
    }
}

Why’s this bad? I don’t like that we’re just returning nothing in the error case. I don’t like that we lost the conciseness of the ?. I suspect there’s a better way, so I ask for a hint. It seems that

If other functions can return a `Result`, why shouldn't `main`? It's a fairly common convention to return something like Result<(), ErrorType> from your main function.
The unit (`()`) type is there because nothing is really needed in terms of positive
results.

Returning a Result from main seems like a fine idea, though I didn’t think of it!

This is what I end up with - still satisfies the prompt and compiles, but it is closer to what the hint implies.

fn main() -> Result<(), ParseIntError>{
    let mut tokens = 100;
    let pretend_user_input = "8";

    let cost = total_cost(pretend_user_input)?;

    if cost > tokens {
        println!("You can't afford that many!");
    } else {
        tokens -= cost;
        println!("You now have {} tokens.", tokens);
    }
    return Ok(())
}

Errors 5 and the first occurrence of Box

Box is a … type? container? A type in Rust which provides more flexibility than I am used to - it allows for any type implementing a trait. In this exercise I find that a Box containing an error::Error can be used to tie together a function that can return multiple types of errors.

No Last Words © 2025