Better way to handle File::open and read_to_end errors

So this is really going to expose how much of a beginner Rustacean I am.....there must be a better way to write this:

    if let Ok(mut file) = File::open(home.unwrap().join("cert.pfx")) {
        match file.read_to_end(&mut buf) {
            Ok(_) => {},
            Err(_) => return Err(SimpleError::new("Unable to read cert.pfx file"))
        }
    } else {
        return Err(SimpleError::new("Unable to read cert.pfx file"))
    }

I'm using the simple-error crate because for now I just want simple error messages and this seems a little bit better than just printing stuff to the console but the match inside of the if let just seems ridiculous.

Is there a way to handle these two potential errors all in one go? If the program fails to open the file and/or fails to read the entire file, the whole program will fail (this is an unrecoverable error).

This way looks a lot cleaner but I really don't want to panic:

    File::open(home.unwrap().join("cert.pfx"))
        .expect("opening cert.pfx")
        .read_to_end(&mut buf)
        .expect("reading cert.pfx");

I want more of a "proper" error with a nice message and maybe a suggestion as to what to do to fix it. Is there a way to essentially replace the two lines with the expect calls and just throw a SimpleError there without creating the monstrosity above?

since your function returns a Result you can use the ? operator.
It unwraps the value or makes an early return instead of panic.
And to adjust the error you can use the map_err() method on Result

File::open(home.unwrap().join("cert.pfx"))
    .map_err(|_| SimpleError::new("Unable to read cert.pfx file"))?
    .read_to_end(&mut buf)
    .map_err(|_| SimpleError::new("Unable to read cert.pfx file"))?;

using the ? on a Result

result?

is the same as

match result {
    Ok(val) => val,
    Err(err) => return err.into()
}

A Shortcut for Propagating Errors: the ? Operator

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.