error handling part 1.5
This commit is contained in:
parent
e661921539
commit
a8e6c2449b
7 changed files with 36 additions and 23 deletions
|
|
@ -28,6 +28,7 @@ tar = { version = "0.4" }
|
|||
zip = { version = "0.6" }
|
||||
async-trait = { version = "0.1" }
|
||||
thiserror = { version = "1" }
|
||||
anyhow = { version = "1" }
|
||||
|
||||
[profile.dev]
|
||||
# Make compilation faster on macOS
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ uuid = { workspace = true }
|
|||
async-trait = { workspace = true }
|
||||
prisma-client-rust = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
anyhow = { workspace = true }
|
||||
|
||||
[features]
|
||||
# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ use serde_json::json;
|
|||
use tauri::{AppHandle, Runtime};
|
||||
use tauri_plugin_shell::ShellExt;
|
||||
|
||||
use crate::{constants::CLIENT_ID, utils::http::create_client};
|
||||
use crate::{constants::CLIENT_ID, utils::http::create_client, PolyResult};
|
||||
|
||||
use super::{Account, AuthenticationMethod};
|
||||
|
||||
pub(super) struct MicrosoftAuthenticationMethod;
|
||||
impl AuthenticationMethod for MicrosoftAuthenticationMethod {
|
||||
async fn auth<R: Runtime, F>(handle: &AppHandle<R>, stage: F) -> <Account, Box<dyn Error>>
|
||||
async fn auth<R: Runtime, F>(handle: &AppHandle<R>, stage: F) -> PolyResult<Account>
|
||||
where F: Fn(String, u8, bool) -> () {
|
||||
|
||||
stage("Authenticating with Microsoft".into(), 0, false);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use std::error::Error;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tauri::{plugin::TauriPlugin, AppHandle, Manager, Runtime};
|
||||
use tauri_plugin_http::reqwest::Client;
|
||||
|
||||
use crate::{PolyError, PolyResult};
|
||||
|
||||
use self::microsoft_auth::MicrosoftAuthenticationMethod;
|
||||
|
||||
mod microsoft_auth;
|
||||
|
|
@ -27,10 +27,10 @@ pub struct AccountSkin {
|
|||
pub trait AuthenticationMethod {
|
||||
/// Authenticate with a given method. Stage is a function that takes a string and a u8.
|
||||
/// The string is the message to display to the user, and the u8 is the progress of the authentication.
|
||||
async fn auth<R: Runtime, F>(handle: &AppHandle<R>, stage: F) -> Result<Account, Box<dyn Error>>
|
||||
async fn auth<R: Runtime, F>(handle: &AppHandle<R>, stage: F) -> PolyResult<Account>
|
||||
where F: Fn(String, u8, bool) -> ();
|
||||
|
||||
async fn get_profile(access_token: String) -> Result<Account, Box<dyn Error>> {
|
||||
async fn get_profile(access_token: String) -> PolyResult<Account> {
|
||||
let response = Client::new()
|
||||
.get("https://api.minecraftservices.com/minecraft/profile")
|
||||
.header("Authorization", format!("Bearer {}", access_token))
|
||||
|
|
@ -39,7 +39,7 @@ pub trait AuthenticationMethod {
|
|||
|
||||
let response = response.json::<serde_json::Value>().await?;
|
||||
if let Some(error) = response.get("error") {
|
||||
return Err(error.to_string().into());
|
||||
return Err(PolyError(error.to_string()));
|
||||
}
|
||||
|
||||
let account = serde_json::from_value::<Account>(response)?;
|
||||
|
|
@ -64,4 +64,4 @@ async fn login_msa<R: tauri::Runtime>(app: tauri::AppHandle<R>) -> Result<Accoun
|
|||
Ok(account) => Ok(account),
|
||||
Err(err) => Err(err.to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,9 +36,15 @@ pub enum PolyError {
|
|||
#[error("failed to establish a connection to the database: {0}")]
|
||||
/// Wrapper around [`prisma_client_rust::NewClientError`] to handle errors occuring while programmatically connecting to Prisma.
|
||||
DBConnectionError(#[from] prisma_client_rust::NewClientError),
|
||||
#[error("failed to establish a HTTP connection: {0}")]
|
||||
/// Wrapper around [`reqwest::Error`] to handle HTTP errors.
|
||||
HTTPError(#[from] tauri_plugin_http::reqwest::Error),
|
||||
#[error("failed to download java: {0}")]
|
||||
/// Wrapper around [`game::client::JavaDownloadError`] to handle Java executable downloading.
|
||||
JavaError(#[from] game::client::JavaDownloadError),
|
||||
#[error("file management failed: {0}")]
|
||||
/// Wrapper around [`utils::file::FileError`] to handle file management errors.
|
||||
FileError(#[from] utils::file::FileError),
|
||||
}
|
||||
|
||||
/// Alias for a [`Result`] with the error type [`PolyError`].
|
||||
|
|
|
|||
|
|
@ -1,27 +1,32 @@
|
|||
use std::{error::Error, fs::File, path::Path};
|
||||
use std::{fs::File, path::Path};
|
||||
use anyhow::anyhow;
|
||||
use thiserror::Error;
|
||||
|
||||
pub fn extract_archive(archive: &Path, dest: &Path) -> Result<(), Box<dyn Error>> {
|
||||
use crate::{PolyError, PolyResult};
|
||||
|
||||
pub fn extract_archive(archive: &Path, dest: &Path) -> PolyResult<()> {
|
||||
let ext = match archive.extension() {
|
||||
Some(ext) => ext.to_str().unwrap(),
|
||||
None => return Err("Archive has no extension".into())
|
||||
None => return Err(anyhow!("unsupported archive type"))
|
||||
};
|
||||
|
||||
match ext {
|
||||
"zip" => extract_zip(archive, dest),
|
||||
"gz" => extract_tar_gz(archive, dest),
|
||||
_ => Err("Unsupported archive type".into())
|
||||
_ => Err(PolyError::FileError(FileError::UnsupportedArch))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extract_zip(archive: &Path, dest: &Path) -> Result<(), Box<dyn Error>> {
|
||||
let mut archive = zip::ZipArchive::new(File::open(archive)?)?;
|
||||
archive.extract(dest)?;
|
||||
pub fn extract_zip(archive: &Path, dest: &Path) -> PolyResult<()> {
|
||||
let mut archive = zip::ZipArchive::new(File::open(archive)?)
|
||||
.map_err(|err| PolyError::FileError(FileError::ZipError(err)));
|
||||
archive?.extract(dest).map_err(|err| PolyError::FileError(FileError::ZipError(err)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn extract_tar_gz(archive: &Path, dest: &Path) -> Result<(), Box<dyn Error>> {
|
||||
pub fn extract_tar_gz(archive: &Path, dest: &Path) -> PolyResult<()> {
|
||||
let tar_gz = flate2::read::GzDecoder::new(File::open(archive)?);
|
||||
let mut archive = tar::Archive::new(tar_gz);
|
||||
archive.unpack(dest)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
use std::{error::Error, fs::File, io::{self, Cursor}, path::Path};
|
||||
use std::{fs::File, io::{self, Cursor}, path::Path};
|
||||
|
||||
use tauri_plugin_http::reqwest::{Client, ClientBuilder};
|
||||
|
||||
use crate::constants::USER_AGENT;
|
||||
use crate::{constants::USER_AGENT, PolyError, PolyResult};
|
||||
|
||||
pub fn create_client() -> Client {
|
||||
pub fn create_client() -> PolyResult<Client> {
|
||||
ClientBuilder::new()
|
||||
.user_agent(USER_AGENT)
|
||||
.build().expect("Failed to create HTTP client. Please report this issue on GitHub.")
|
||||
.build().map_err(|err| PolyError::HTTPError(err))
|
||||
}
|
||||
|
||||
pub async fn download_file(url: &str, path: &Path) -> Result<(), Box<dyn Error>> {
|
||||
let response = create_client().get(url).send().await?;
|
||||
pub async fn download_file(url: &str, path: &Path) -> PolyResult<()> {
|
||||
let response = create_client()?.get(url).send().await?;
|
||||
let mut file = File::create(path)?;
|
||||
let mut content = Cursor::new(response.bytes().await?);
|
||||
io::copy(&mut content, &mut file)?;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue