fix(download manager): fix incorrect error assumptions & update types

This commit is contained in:
DecDuck
2024-12-31 00:08:05 +11:00
parent 472eb1d435
commit a17311a88d
6 changed files with 31 additions and 22 deletions

View File

@ -93,7 +93,9 @@ fn recieve_handshake_logic(app: &AppHandle, path: String) -> Result<(), RemoteAc
let path_chunks: Vec<&str> = path.split("/").collect();
if path_chunks.len() != 3 {
app.emit("auth/failed", ()).unwrap();
return Err(RemoteAccessError::InvalidResponse);
return Err(RemoteAccessError::HandshakeFailed(
"failed to parse token".to_string(),
));
}
let base_url = {

View File

@ -14,18 +14,12 @@ use url::Url;
use crate::{process::process_manager::Platform, DB};
#[derive(serde::Serialize, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DatabaseAuth {
pub private: String,
pub cert: String,
pub client_id: String,
}
pub struct GameStatusData {
version_name: String,
install_dir: String,
}
// Strings are version names for a particular game
#[derive(Serialize, Clone, Deserialize)]
#[serde(tag = "type")]
@ -61,7 +55,6 @@ pub struct GameVersion {
}
#[derive(Serialize, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DatabaseGames {
pub install_dirs: Vec<String>,
// Guaranteed to exist if the game also exists in the app state map
@ -89,6 +82,7 @@ impl Default for Settings {
#[derive(Serialize, Deserialize, Clone)]
pub struct Database {
#[serde(default)]
pub settings: Settings,
pub auth: Option<DatabaseAuth>,
pub base_url: String,
@ -136,8 +130,7 @@ impl DatabaseImpls for DatabaseInterface {
let exists = fs::exists(db_path.clone()).unwrap();
match exists {
true => PathDatabase::load_from_path(db_path)
.expect("Database loading failed"),
true => PathDatabase::load_from_path(db_path).expect("Database loading failed"),
false => {
let default = Database {
settings: Settings::default(),

View File

@ -3,7 +3,8 @@ use crate::db::DatabaseImpls;
use crate::downloads::manifest::DropDownloadContext;
use crate::remote::RemoteAccessError;
use crate::DB;
use log::warn;
use http::StatusCode;
use log::{info, warn};
use md5::{Context, Digest};
use reqwest::blocking::Response;
@ -171,7 +172,10 @@ pub fn download_game_chunk(
let content_length = response.content_length();
if content_length.is_none() {
return Err(GameDownloadError::Communication(
RemoteAccessError::InvalidResponse,
RemoteAccessError::ManifestDownloadFailed(
StatusCode::from_u16(500).unwrap(),
"failed to download manifest due to missing content length".to_owned(),
),
));
}

View File

@ -356,11 +356,8 @@ impl DownloadManagerBuilder {
if let Err(error) =
on_game_complete(game_id, version, install_dir, &self.app_handle)
{
self.sender
.send(DownloadManagerSignal::Error(
GameDownloadError::Communication(error),
))
.unwrap();
error!("failed to mark game as completed: {}", error);
// TODO mark game as remote so user can retry
}
}
}
@ -500,6 +497,7 @@ impl DownloadManagerBuilder {
.unwrap();
}
fn manage_error_signal(&mut self, error: GameDownloadError) {
error!("{}", error);
let current_status = self.current_download_agent.clone().unwrap();
self.stop_and_wait_current_download();

View File

@ -1,16 +1,17 @@
use std::sync::Mutex;
use log::info;
use serde::{Deserialize, Serialize};
use tauri::Emitter;
use tauri::{AppHandle, Manager};
use urlencoding::encode;
use crate::db::DatabaseImpls;
use crate::db::GameVersion;
use crate::db::GameStatus;
use crate::db::GameVersion;
use crate::downloads::download_manager::{DownloadManagerStatus, GameDownloadStatus};
use crate::process::process_manager::Platform;
use crate::remote::RemoteAccessError;
use crate::remote::{DropServerError, RemoteAccessError};
use crate::state::{GameStatusManager, GameStatusWithTransient};
use crate::{auth::generate_authorization_header, AppState, DB};
@ -288,6 +289,14 @@ pub fn on_game_complete(
.header("Authorization", header)
.send()?;
if response.status() != 200 {
return Err(RemoteAccessError::InvalidResponse(
response.json::<DropServerError>().map_err(|e| {
RemoteAccessError::Generic(format!("failed to parse server error: {}", e))
})?,
));
}
let data = response.json::<GameVersion>()?;
let mut handle = DB.borrow_data_mut().unwrap();

View File

@ -6,6 +6,7 @@ use std::{
use http::StatusCode;
use log::{info, warn};
use reqwest::blocking::Response;
use serde::Deserialize;
use url::{ParseError, Url};
@ -19,10 +20,11 @@ pub enum RemoteAccessError {
InvalidEndpoint,
HandshakeFailed(String),
GameNotFound,
InvalidResponse,
InvalidResponse(DropServerError),
InvalidRedirect,
ManifestDownloadFailed(StatusCode, String),
OutOfSync,
Generic(String),
}
impl Display for RemoteAccessError {
@ -45,7 +47,7 @@ impl Display for RemoteAccessError {
RemoteAccessError::InvalidEndpoint => write!(f, "Invalid drop endpoint"),
RemoteAccessError::HandshakeFailed(message) => write!(f, "Failed to complete handshake: {}", message),
RemoteAccessError::GameNotFound => write!(f, "Could not find game on server"),
RemoteAccessError::InvalidResponse => write!(f, "Server returned an invalid response"),
RemoteAccessError::InvalidResponse(error) => write!(f, "Server returned an invalid response: {} {}", error.status_code, error.status_message),
RemoteAccessError::InvalidRedirect => write!(f, "Server redirect was invalid"),
RemoteAccessError::ManifestDownloadFailed(status, response) => write!(
f,
@ -53,6 +55,7 @@ impl Display for RemoteAccessError {
status, response
),
RemoteAccessError::OutOfSync => write!(f, "Server's and client's time are out of sync. Please ensure they are within at least 30 seconds of each other."),
RemoteAccessError::Generic(message) => write!(f, "{}", message),
}
}
}
@ -75,7 +78,7 @@ impl From<u16> for RemoteAccessError {
impl std::error::Error for RemoteAccessError {}
#[derive(Deserialize)]
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DropServerError {
pub status_code: usize,