Implement better error system and segregate errors and commands (#23)

* chore: Progress on amend_settings command

Signed-off-by: quexeky <git@quexeky.dev>

* chore(errors): Progress on better error handling with segragation of files

* chore: Progress on amend_settings command

Signed-off-by: quexeky <git@quexeky.dev>

* chore(commands): Separated commands under each subdirectory into respective commands.rs files

Signed-off-by: quexeky <git@quexeky.dev>

* chore(errors): Almost all errors and commands have been segregated

* chore(errors): Added drop server error

Signed-off-by: quexeky <git@quexeky.dev>

* feat(core): Update to using nightly compiler

Signed-off-by: quexeky <git@quexeky.dev>

* chore(errors): More progress on error handling

Signed-off-by: quexeky <git@quexeky.dev>

* chore(errors): Implementing Try and FromResidual for UserValue

Signed-off-by: quexeky <git@quexeky.dev>

* refactor(errors): Segregated errors and commands from code, and made commands return UserValue struct

Signed-off-by: quexeky <git@quexeky.dev>

* fix(errors): Added missing files

* chore(errors): Convert match statement to map_err

* feat(settings): Implemented settings editing from UI

* feat(errors): Clarified return values from retry_connect command

* chore(errors): Moved autostart commands to autostart.rs

* chore(process manager): Converted launch_process function for games to use game_id

---------

Signed-off-by: quexeky <git@quexeky.dev>
This commit is contained in:
quexeky
2025-01-13 21:44:57 +11:00
committed by GitHub
parent 245a84d20b
commit 604d5b5884
45 changed files with 822 additions and 600 deletions

View File

@ -1,43 +0,0 @@
use std::{
fmt::{Display, Formatter},
io,
};
use crate::remote::RemoteAccessError;
// TODO: Rename / separate from downloads
#[derive(Debug, Clone)]
pub enum ApplicationDownloadError {
Communication(RemoteAccessError),
Checksum,
Setup(SetupError),
Lock,
IoError(io::ErrorKind),
DownloadError,
}
impl Display for ApplicationDownloadError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
ApplicationDownloadError::Communication(error) => write!(f, "{}", error),
ApplicationDownloadError::Setup(error) => write!(f, "An error occurred while setting up the download: {}", error),
ApplicationDownloadError::Lock => write!(f, "Failed to acquire lock. Something has gone very wrong internally. Please restart the application"),
ApplicationDownloadError::Checksum => write!(f, "Checksum failed to validate for download"),
ApplicationDownloadError::IoError(error) => write!(f, "{}", error),
ApplicationDownloadError::DownloadError => write!(f, "Download failed. See Download Manager status for specific error"),
}
}
}
#[derive(Debug, Clone)]
pub enum SetupError {
Context,
}
impl Display for SetupError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
SetupError::Context => write!(f, "Failed to generate contexts for download"),
}
}
}

View File

@ -0,0 +1,31 @@
use std::sync::{mpsc::SendError, Arc, Mutex};
use crate::{download_manager::downloadable_metadata::DownloadableMetadata, AppState};
#[tauri::command]
pub fn pause_downloads(state: tauri::State<'_, Mutex<AppState>>) {
state.lock().unwrap().download_manager.pause_downloads()
}
#[tauri::command]
pub fn resume_downloads(state: tauri::State<'_, Mutex<AppState>>) {
state.lock().unwrap().download_manager.resume_downloads()
}
#[tauri::command]
pub fn move_download_in_queue(
state: tauri::State<'_, Mutex<AppState>>,
old_index: usize,
new_index: usize,
) {
state
.lock()
.unwrap()
.download_manager
.rearrange(old_index, new_index)
}
#[tauri::command]
pub fn cancel_game(state: tauri::State<'_, Mutex<AppState>>, meta: DownloadableMetadata) {
state.lock().unwrap().download_manager.cancel(meta)
}

View File

@ -12,8 +12,9 @@ use std::{
use log::info;
use serde::Serialize;
use crate::error::application_download_error::ApplicationDownloadError;
use super::{
application_download_error::ApplicationDownloadError,
download_manager_builder::{CurrentProgressObject, DownloadAgent},
downloadable_metadata::DownloadableMetadata,
queue::Queue,

View File

@ -7,13 +7,15 @@ use std::{
thread::{spawn, JoinHandle},
};
use log::info;
use log::{debug, error, info};
use tauri::{AppHandle, Emitter};
use crate::games::library::{QueueUpdateEvent, QueueUpdateEventQueueData, StatsUpdateEvent};
use crate::{
error::application_download_error::ApplicationDownloadError,
games::library::{QueueUpdateEvent, QueueUpdateEventQueueData, StatsUpdateEvent},
};
use super::{
application_download_error::ApplicationDownloadError,
download_manager::{DownloadManager, DownloadManagerSignal, DownloadManagerStatus},
download_thread_control_flag::{DownloadThreadControl, DownloadThreadControlFlag},
downloadable::Downloadable,
@ -54,7 +56,7 @@ whichever download queue order is required.
+----------------------------------------------------------------------------+
This download queue does not actually own any of the DownloadAgents. It is
simply a id-based reference system. The actual Agents are stored in the
simply an id-based reference system. The actual Agents are stored in the
download_agent_registry HashMap, as ordering is no issue here. This is why
appending or removing from the download_queue must be done via signals.
@ -239,6 +241,7 @@ impl DownloadManagerBuilder {
match download_agent.download(&app_handle) {
// Ok(true) is for completed and exited properly
Ok(true) => {
debug!("download {:?} has completed", download_agent.metadata());
download_agent.on_complete(&app_handle);
sender
.send(DownloadManagerSignal::Completed(download_agent.metadata()))
@ -249,6 +252,7 @@ impl DownloadManagerBuilder {
download_agent.on_incomplete(&app_handle);
}
Err(e) => {
error!("download {:?} has error {}", download_agent.metadata(), &e);
download_agent.on_error(&app_handle, e.clone());
sender.send(DownloadManagerSignal::Error(e)).unwrap();
}

View File

@ -2,9 +2,10 @@ use std::sync::Arc;
use tauri::AppHandle;
use crate::error::application_download_error::ApplicationDownloadError;
use super::{
application_download_error::ApplicationDownloadError, download_manager::DownloadStatus,
download_thread_control_flag::DownloadThreadControl,
download_manager::DownloadStatus, download_thread_control_flag::DownloadThreadControl,
downloadable_metadata::DownloadableMetadata, progress_object::ProgressObject,
};

View File

@ -1,4 +1,4 @@
pub mod application_download_error;
pub mod commands;
pub mod download_manager;
pub mod download_manager_builder;
pub mod download_thread_control_flag;

View File

@ -138,19 +138,22 @@ impl ProgressObject {
}
}
#[throttle(10, Duration::from_secs(1))]
#[throttle(50, Duration::from_secs(1))]
fn update_ui(progress_object: &ProgressObject, kilobytes_per_second: usize, time_remaining: usize) {
progress_object.sender
.send(DownloadManagerSignal::UpdateUIStats(
kilobytes_per_second,
time_remaining,
))
.unwrap();
progress_object
.sender
.send(DownloadManagerSignal::UpdateUIStats(
kilobytes_per_second,
time_remaining,
))
.unwrap();
}
#[throttle(10, Duration::from_secs(1))]
#[throttle(50, Duration::from_secs(1))]
fn update_queue(progress: &ProgressObject) {
progress.sender
progress
.sender
.send(DownloadManagerSignal::UpdateUIQueue)
.unwrap();
}
}