简体   繁体   中英

Rust — How to handle error precisely and gracefully?

Sorry for naming this a so ambiguous title, but I can't come up with a better one.

The read_dir() method defined in std::fs returns instances of io::Result<DirEntry> , which is the alias of Result<DirEntry, io::Error> . When the caller does not exist on file system, it returns the error.

Now my code is

dir_a.read_dir();
dir_b.read_dir();
dir_c.read_dir();

And dir_a , dir_b , dir_c all may not exist. So these three statements may return the same io::Error , but for my program, dir_a , dir_b and dir_c have different meaning, where I want to handle the error for each one respectively.

So I defined my own enum MyError as

enum MyError {
    Dir_a_not_exist,
    Dir_b_not_exist,
    Dir_c_not_exist,
}

How can I transform the same io::Error to my different three MyError ?

My ugly way is to

match dir_a.read_dir() {
    Ok => match dir_b.read_dir() {
              Ok => match dir_c.read_dir() {
                        Ok => { /* do something */ },
                        Err => return MyError::Dir_c_not_exist,
                    },
              Err => return MyError::Dir_b_not_exist,
          },
    Err => return MyError::Dir_a_not_exist,
};

Is there any graceful way I can handle this?

Result has a function called or , that allows you to forward the result if it's Ok, or transform it if it's an error. With that, you can do something like this:

fn foo(dir_a: &Path, dir_b: &Path, dir_c: &Path) -> Result<(), MyError> {
    dir_a.read_dir().or(Err(MyError::DirAnotExist))?;
    dir_b.read_dir().or(Err(MyError::DirBnotExist))?;
    dir_c.read_dir().or(Err(MyError::DirCnotExist))?;

    /* do something */

    Ok(())
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM