Error Handling in Rust

There are a lot of things to love about Rust, not least of which are its excellent documentation and package handler (Cargo). But I also really like the error handling.

In Rust, you can choose to handle the error via having the program panic (which will abort the entire program), but this is generally considered something best avoided – especially if you are writing a program that other people will be using.

if n < 1 || n > 10 {
        panic!("Invalid number: {}", n);
    }

For example, if you had this in your code, and you passed in a number lower than n or greater than 10, you would not get a very good error message and it would be annoying.

An exception would be if the error is raised by something that should not happen and therefore indicating an actual bug in the program (and not simply the user typing the wrong thing, etc). In this case, you would want your program to panic and stop everything – because there is something way wrong that you didn’t foresee (and so probably could not have written a specific case for it).

You can unwrap something, which will either return the result of a computation or panic. But this, of course, runs into a lot of the same annoying things as panic.

You can also specify that, if you run into an error, for the program to simply continue. For example:

fn main() {
    println!("Guess the number!");
    println!("Enter your guess:");

    let secret_number = rand::thread_rng().gen_range(1, 101);
    
    loop {
        let mut guess = String::new();

        io::stdin().read_line(&mut guess)
        .expect("Failed to read input");

        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => continue,
        };

        println!("You guessed {}", guess);

        match guess.cmp(&secret_number) {
            Ordering::Less => println!("Higher!"),
            Ordering::Greater => println!("Lower!"),
            Ordering::Equal => {
                println!("You Win!");
                break;    
            }
        }
    }
}

If the person types in something that is a number, then it will be compared to the randomly generated number and told whether they have won or not. But if the person types in something that is not a number, then the the program will continue and the rest of the loop will simply skip and then ask the user to enter another number.

And there are many more ways to handle errors in Rust. You can write error messages for what happens when no arguments were passed when they were expected, or to display a different error if the argument fails to parse (and therefore is not the appropriate type), or to simply proceed as normal if everything checks out:

fn double_arg(mut argv: env::Args) -> Result<i32, String> {
    argv.nth(1)
        .ok_or("Please give at least one argument".to_owned())
        .and_then(|arg| arg.parse::<i32>().map_err(|err| err.to_string()))
        .map(|n| 2 * n)
}

fn main() {
    match double_arg(env::args()) {
        Ok(n) => println!("{}", n),
        Err(err) => println!("Error: {}", err),
    }
}

And there are many more ways to write helpful error messages and to handle the errors in such a way that your program behaves the way it should (which includes panic-ing when needed). This is just another part of what makes Rust so powerful and such a pleasure to work with.

Continuing on Memory Lane with Dungeon Keeper 2

I’ve been continuing on down memory lane with Dungeon Keeper II, and have almost finished with the campaign. I just finished storming the Faerie Fortress.

imps-digging
Imps breaking down the back wall of the Faerie Fortress

It has been a lot of fun reliving the campaign. Soon now, I will get to the Dark Angel part in the campaign!

Weekend of Firsts

This Saturday my sister invited me to go see “The Book of Mormon” at the Orpheum Theatre.

image

So I finally got to see it. It was fun and I liked the music and sets a lot. I’m not sure about some of the plot points (went too far in the “Last Samurai” direction rather than in the “Seven Samurai” direction), but overall it seemed positive and lighthearted enough that it was pretty fun despite the tired old white-man-comes-to-save-non-white-village trope. I think I would have liked the show better, and that it would have been more fun, if the villagers all stood up for and saved themselves. They hinted at this, and sort of tried to go in that direction (like I said, it was in-between “Last Samurai” and “Seven Samurai”), but ultimately it did not go far enough in that direction. Oh, well.

Afterwards, we went to Brewcade in the Castro and got helplessly addicted to a 10-player (5 vs 5) game they had called “Killer Queen.” It is a game of strategy involving bees. We played it for about 4 hours straight. Since there were only 4 people in our group, we got to play with (and against) an ever-rotating cadre of randos. When there were no randos that wanted to play, we just did 2 vs 2 games. Luckily the game is pretty intuitive, such that people who looked curious could just jump in at any time and pick it up.

Doc and I went back to Brewcade to play Killer Queen again on Sunday. I am not ashamed of this.

I had also never been to Brewcade before, so I was happy to finally be able to check it out for myself. A lot of my friends had been saying it was disappointing, but I thought it was pretty good. A nice beer selection of mostly California beers, and Paperboy. Really, what more can you ask for?