Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: proper rust error handling #112

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/backend-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@ jobs:
with:
name: clippy (${{ runner.os }})
token: ${{ secrets.GITHUB_TOKEN }}
args: --manifest-path ./src-tauri/Cargo.toml --no-default-features -- -D warnings
args: --manifest-path ./src-tauri/Cargo.toml --no-default-features
13 changes: 13 additions & 0 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ hudsucker = "0.18.0"
tracing = "0.1.37"
tokio-rustls = "0.23.4"
tokio-tungstenite = "0.17.2"
tokio = { version = "1.21.2", features = ["signal"] }
tokio = { version = "1.21.2", features = ["signal", "macros", "rt-multi-thread"] }
rustls-pemfile = "1.0.1"
reqwest = { version = "0.11.13", features = ["stream"] }
futures-util = "0.3.25"
Expand All @@ -63,11 +63,12 @@ regex = "1"
file_diff = "1.0.0"
rust-ini = "0.18.0"
ctrlc = "3.2.3"
thiserror = "1.0.37"

[features]
# by default Tauri runs in production mode
# when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL
default = [ "custom-protocol" ]
default = ["custom-protocol"]
# this feature is used used for production builds where `devPath` points to the filesystem
# DO NOT remove this
custom-protocol = [ "tauri/custom-protocol" ]
custom-protocol = ["tauri/custom-protocol"]
6 changes: 3 additions & 3 deletions src-tauri/lang/vi.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@
"gc_dev_data": "Tải xuống tệp dữ liệu phiên bản mới nhất của Grasscutter. Bản này không đi kèm với tập tin jar, hữu dụng khi muốn cập nhật.",
"encryption": "Mục này nên được tắt.",
"resources": "Tài nguyên được yêu cầu để chạy máy chủ Grasscutter. Nút này sẽ có màu xám nếu bạn đã có sẵn một thư mục tài nguyên (resources) có nội dung bên trong",
"emergency_metadata": "Trong trường hợp gặp vấn đề, khôi phục lại metadata về phiên bản chính thức mới nhất.",
"use_proxy": "Sử dụng proxy nội bộ của Cultivation. Nên bật tùy chọn này trừ khi bạn đang sử dụng một ứng dụng khác, như Fiddler",
"patch_metadata": "Tự động vá và sửa lại metadata của game. Tùy chọn này nên được bật trừ khi bạn đang sử dụng phiên bản cũ, phiên bản không chính thức hoặc bạn đã tự vá metadata rồi."
"emergency_metadata": "Trong trường hợp gặp vấn đề, khôi phục lại metadata về phiên bản chính thức mới nhất.",
"use_proxy": "Sử dụng proxy nội bộ của Cultivation. Nên bật tùy chọn này trừ khi bạn đang sử dụng một ứng dụng khác, như Fiddler",
"patch_metadata": "Tự động vá và sửa lại metadata của game. Tùy chọn này nên được bật trừ khi bạn đang sử dụng phiên bản cũ, phiên bản không chính thức hoặc bạn đã tự vá metadata rồi."
},
"swag": {
"akebi_name": "Akebi",
Expand Down
4 changes: 4 additions & 0 deletions src-tauri/rustfmt.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ newline_style = "Unix"
tab_spaces = 2
use_field_init_shorthand = true
use_try_shorthand = true
format_code_in_doc_comments = true
wrap_comments = true
format_strings = true
imports_granularity = "Crate"
3 changes: 3 additions & 0 deletions src-tauri/src/admin.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#[cfg(windows)]
pub fn reopen_as_admin() {
use std::process::{exit, Command};

let install = std::env::current_exe().unwrap();

println!("Opening as admin: {}", install.to_str().unwrap());
Expand All @@ -16,5 +18,6 @@ pub fn reopen_as_admin() {
exit(0);
}

#[allow(unused)]
#[cfg(target_os = "linux")]
pub fn reopen_as_admin() {}
12 changes: 4 additions & 8 deletions src-tauri/src/downloader.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
use once_cell::sync::Lazy;

use std::cmp::min;
use std::fs::File;
use std::io::Write;
use std::sync::Mutex;
use std::{cmp::min, fs::File, io::Write, sync::Mutex};

use futures_util::StreamExt;

// This will create a downloads list that will be used to check if we should continue downloading the file
// This will create a downloads list that will be used to check if we should
// continue downloading the file
static DOWNLOADS: Lazy<Mutex<Vec<String>>> = Lazy::new(|| Mutex::new(Vec::new()));

// Lots of help from: https://gist.github.com/giuliano-oliveira/4d11d6b3bb003dba3a1b53f43d81b30d
Expand Down Expand Up @@ -111,7 +109,5 @@ pub fn stop_download(path: String) {
}

// Delete the file from disk
if let Err(_e) = std::fs::remove_file(&path) {
// Do nothing
}
std::fs::remove_file(&path).unwrap_or(());
}
71 changes: 71 additions & 0 deletions src-tauri/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use serde::Serialize;
use thiserror::Error;

/*
This will not have mutex lock error
because we are going to get rid of locking data structures so
we can leave unwraps `as is` for now
*/

#[derive(Debug, Error)]
/// Error type to signal about different errors that could occur
/// while Cultivation is running.
pub enum CultivationError {
// We hide sensitive information in production
#[cfg_attr(debug_assertions, error("IO error has occured: {:?}", .0))]
#[cfg_attr(not(debug_assertions), error("IO error has occured."))]
IO(#[from] tokio::io::Error),
#[cfg_attr(debug_assertions, error("Tauri failed with an error: {}", .0))]
#[cfg_attr(not(debug_assertions), error("Tauri failed with an error"))]
Tauri(#[from] tauri::Error),
#[cfg_attr(debug_assertions, error("Failed to create zip archive: {}", .0))]
#[cfg_attr(not(debug_assertions), error("Zip related function has failed"))]
Zip(#[from] zip::result::ZipError),
#[cfg_attr(debug_assertions, error("Failed to unzip archive: {}", .0))]
#[cfg_attr(not(debug_assertions), error("Failed to unzip archive"))]
Unzip(#[from] zip_extract::ZipExtractError),
#[cfg_attr(debug_assertions, error("Failed to unrar: {}", .0))]
#[cfg_attr(not(debug_assertions), error("Failed to unrar"))]
Unrar(#[from] UnrarError),
#[cfg_attr(debug_assertions, error("HTTP request failed: {}", .0))]
#[cfg_attr(not(debug_assertions), error("HTTP request failed"))]
Reqwest(#[from] reqwest::Error),
#[cfg_attr(debug_assertions, error("Malformed language config: {}", .0))]
#[cfg_attr(not(debug_assertions), error("Malformed language config"))]
MalformedLangObject(#[from] serde_json::Error),
#[cfg_attr(debug_assertions, error("Ctrlc handler failed: {}", .0))]
#[cfg_attr(
not(debug_assertions),
error("Could not set graceful shutdown handler")
)]
CtrlCError(#[from] ctrlc::Error),
#[cfg_attr(debug_assertions, error("Certificate generation failed: {}", .0))]
#[cfg_attr(not(debug_assertions), error("Certificate generation has failed."))]
Certificate(#[from] rcgen::RcgenError),
#[cfg_attr(debug_assertions, error("Custom error: {}", .0))]
#[cfg_attr(not(debug_assertions), error("Something went wrong"))]
#[allow(unused)]
Custom(String),
}

#[derive(Debug, Error)]
#[cfg_attr(debug_assertions, error("Failed to unrar: {}", .0))]
#[cfg_attr(not(debug_assertions), error("Failed to unrar"))]
pub struct UnrarError(String);

impl<T> From<unrar::error::UnrarError<T>> for UnrarError {
fn from(value: unrar::error::UnrarError<T>) -> Self {
Self(value.to_string())
}
}

impl Serialize for CultivationError {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(self.to_string().as_ref())
}
}

pub type CultivationResult<T> = Result<T, CultivationError>;
Loading