Improve error handling for loading the library

This commit is contained in:
Elias Projahn 2025-03-23 09:59:28 +01:00
parent f977cac3fd
commit d12e6a02a4
2 changed files with 64 additions and 28 deletions

View file

@ -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<Path>) -> Self {
glib::Object::builder()
pub fn new(path: impl AsRef<Path>) -> Result<Self> {
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)]

View file

@ -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<Path>) {
let library = Library::new(path);
fn load_library(&self, path: impl AsRef<Path>) -> 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<Path>) -> 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) {