What is idiomatic error handling with cleanup of external state

Say you created some files and/or directories which need to stay after the program exits, unless something went wrong in which case you want to remove all of them. This is a general problem, I'm using files as something which is easy to reason about.

I was unable to find documentation how to handle this in Rust -- all error handling I had seen straight up ignores the problem.

For instance create - Rust By Example :

    // Open a file in write-only mode, returns `io::Result<File>`
    let mut file = match File::create(&path) {
        Err(why) => panic!("couldn't create {}: {}", display, why),
        Ok(file) => file,
    };

    // Write the `LOREM_IPSUM` string to `file`, returns `io::Result<()>`
    match file.write_all(LOREM_IPSUM.as_bytes()) {
        Err(why) => panic!("couldn't write to {}: {}", display, why),
        Ok(_) => println!("successfully wrote to {}", display),
    }

If write_all fails (say there is not enough space), the program exits leaving the created file behind.

For this particular case it is easy enough to sort out, but what is the way to do it for a more involved scenario -- say you have 3 or more files created this way, what do you do?

In C where I come from you would roll with a bunch of goto labels, but that's error prone and I figured Rust may be able to do better. I just don't see it documented anywhere.

Other than just manually writing it out, you can create your own struct with a destructor that deletes the file.

5 Likes

For the file case[1] you can use some crate that handles a temp directory for you, and move the files once they're written successfully.


  1. which I recognize is not every case ↩ī¸Ž

2 Likes