From d12e6a02a4fbf516e9b3f6dacbf483c74cf60609 Mon Sep 17 00:00:00 2001 From: Elias Projahn Date: Sun, 23 Mar 2025 09:59:28 +0100 Subject: [PATCH] Improve error handling for loading the library --- src/library.rs | 44 +++++++++++++++++++++++++------------------- src/window.rs | 48 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 64 insertions(+), 28 deletions(-) diff --git a/src/library.rs b/src/library.rs index eaba4f5..0be701a 100644 --- a/src/library.rs +++ b/src/library.rs @@ -13,7 +13,7 @@ use adw::{ prelude::*, subclass::prelude::*, }; -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Context, Result}; use chrono::prelude::*; use diesel::{dsl::exists, prelude::*, sql_types, QueryDsl, SqliteConnection}; use once_cell::sync::Lazy; @@ -55,21 +55,6 @@ mod imp { SIGNALS.as_ref() } - - fn constructed(&self) { - self.parent_constructed(); - - let db_path = PathBuf::from(&self.folder.get().unwrap()).join("musicus.db"); - let connection = db::connect(db_path.to_str().unwrap()).unwrap(); - - if self - .connection - .set(Arc::new(Mutex::new(connection))) - .is_err() - { - panic!("connection should not be set"); - } - } } } @@ -78,10 +63,13 @@ glib::wrapper! { } impl Library { - pub fn new(path: impl AsRef) -> Self { - glib::Object::builder() + pub fn new(path: impl AsRef) -> Result { + let obj: Self = glib::Object::builder() .property("folder", path.as_ref().to_str().unwrap()) - .build() + .build(); + + obj.init()?; + Ok(obj) } /// Import from a library archive. @@ -1736,6 +1724,24 @@ impl Library { obj.emit_by_name::<()>("changed", &[]); }); } + + fn init(&self) -> Result<()> { + let db_path = PathBuf::from(&self.folder()).join("musicus.db"); + + let connection = db::connect( + db_path + .to_str() + .ok_or_else(|| anyhow!("Failed to convert libary path to string"))?, + ) + .context("Failed to connect to music library database")?; + + self.imp() + .connection + .set(Arc::new(Mutex::new(connection))) + .map_err(|_| anyhow!("Library already initialized"))?; + + Ok(()) + } } #[derive(Clone, Default, Debug)] diff --git a/src/window.rs b/src/window.rs index cbaefac..98e6ffd 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,6 +1,7 @@ use std::{cell::RefCell, path::Path}; use adw::{prelude::*, subclass::prelude::*}; +use anyhow::{anyhow, Result}; use gettextrs::gettext; use gtk::{gio, glib, glib::clone}; @@ -15,6 +16,7 @@ use crate::{ preferences_dialog::PreferencesDialog, process_manager::ProcessManager, search_page::SearchPage, + util, welcome_page::WelcomePage, }; @@ -142,7 +144,9 @@ mod imp { let settings = gio::Settings::new(config::APP_ID); let library_path = settings.string("library-path").to_string(); if !library_path.is_empty() { - self.obj().load_library(&library_path); + if let Err(err) = self.obj().load_library(&library_path) { + util::error_toast("Failed to open music library", err, &self.toast_overlay); + } } } } @@ -225,16 +229,28 @@ impl Window { pub fn set_library_folder(&self, folder: &gio::File) { let path = folder.path().unwrap(); - let settings = gio::Settings::new(config::APP_ID); - settings - .set_string("library-path", path.to_str().unwrap()) - .unwrap(); - - self.load_library(path); + match self.load_library(&path) { + Ok(_) => { + if let Err(err) = self.save_library_path(path) { + util::error_toast( + "Failed to save library folder", + err, + &self.imp().toast_overlay, + ); + } + } + Err(err) => { + util::error_toast( + "Failed to open music library", + err, + &self.imp().toast_overlay, + ); + } + } } - fn load_library(&self, path: impl AsRef) { - let library = Library::new(path); + fn load_library(&self, path: impl AsRef) -> Result<()> { + let library = Library::new(path)?; library.connect_changed(clone!( #[weak(rename_to = obj)] @@ -245,6 +261,20 @@ impl Window { self.imp().player.set_library(&library); self.imp().library.replace(Some(library)); self.reset_view(); + + Ok(()) + } + + fn save_library_path(&self, path: impl AsRef) -> Result<()> { + let settings = gio::Settings::new(config::APP_ID); + settings.set_string( + "library-path", + path.as_ref() + .to_str() + .ok_or_else(|| anyhow!("Failed to convert path to string"))?, + )?; + + Ok(()) } fn reset_view(&self) {