Is this good style or not? Nested unwrap_or_else

I was able to avoid writing some code twice using this method, but I was wondering if this is considered good style or not.

// Set the config file path
    let config_path = settings::return_config_path(chain).unwrap_or_else(|err| {
        println!("Error: {}, falling back to working directory", err);
        //If there is an error set it to the current working directory
        settings::return_local_path(chain).unwrap_or_else(|err| {
            println!("{}", err);
            std::process::exit(1);
        })
    });

It certainly feels a little unnecessarily nested.
Wouldn't something like this work and look better?

let config_path = settings::return_config_path(chain)
    .or_else(|_| settings::return_local_path(chain))
    .unwrap_or_else(|err| {
        println!("{}", err);
        std::process::exit(1);
    });

PS: Ok, missed the first println!, but I guess this can be added here too.

4 Likes

Thanks, works like a charm :). Just getting used to rust, so far loving it, in c++ I had tons of bugs, rust compiler is ace man. I hope the language takes off...

3 Likes

If this is directly in main(), then it's fine. If it's inside any other function, then use Result and the ? operator. Use anyhow if you need a universal error type for these.

1 Like

The ? operator is a good replacement for and_then but not for or_else. Code using or_else should return early on success, not on failure.

1 Like

When nesting is necessary, I feel like match is cleaner than callbacks. However this is just a personal preference.

3 Likes