Grasscutters / Cultivation

A custom launcher designed to make it as easy as possible to proxy anime game traffic to private servers.
Apache License 2.0
974 stars 160 forks source link

Better error handling and reporting #52

Open Seeker14491 opened 2 years ago

Seeker14491 commented 2 years ago

Error handling could use a rework. There's many places in the Rust code where we call unwrap() for things like file system access or downloading stuff, which means Cultivation will crash if any of those operations fail. I think if such an operation fails, we should display that error on the frontend such as with a pop up message. The Rust code will need refactoring first though, so we return Results to the frontend instead of crashing.

Seeker14491 commented 2 years ago

I came up with a really simple way to handle errors on the Rust side: https://github.com/Seeker14491/anyhow-tauri. It's just a fork of the popular error handling library anyhow, but with a tiny tweak that lets you return its error type from Tauri commands. As an example, we can rewrite a function like this one in file_helpers.rs:

#[tauri::command]
pub fn read_file(path: String) -> String {
  let path_buf = std::path::PathBuf::from(&path);

  let mut file = match fs::File::open(path_buf) {
    Ok(file) => file,
    Err(e) => {
      println!("Failed to open file: {}", e);
      return String::new();
    }
  };

  let mut contents = String::new();
  file.read_to_string(&mut contents).unwrap();

  contents
}

into this:

#[tauri::command]
pub fn read_file(path: &Path) -> Result<String> {
  let mut file = File::open(path)?;
  let mut contents = String::new();
  file.read_to_string(&mut contents)?;

  Ok(contents)
}

without any other boilerplate. You can also attach context like in vanilla anyhow:

file.read_to_string(&mut contents).context("helpful error context goes here")?;

If the function errors, on the TypeScript side we can read the error and any context it might have. We can also optionally get a backtrace that shows where the error occurred, at least for debug builds.

Also, for file operations specifically, we can use the fs_err crate to get better error messages.