Show error dialog on migration failure

This commit is contained in:
Gregory Schier
2025-06-04 11:20:28 -07:00
parent 2562cf7c55
commit 021f2171d6
6 changed files with 31 additions and 10 deletions

1
src-tauri/Cargo.lock generated
View File

@@ -7718,6 +7718,7 @@ dependencies = [
"sha2", "sha2",
"tauri", "tauri",
"tauri-plugin", "tauri-plugin",
"tauri-plugin-dialog",
"thiserror 2.0.12", "thiserror 2.0.12",
"tokio", "tokio",
"ts-rs", "ts-rs",

View File

@@ -54,7 +54,7 @@ serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true, features = ["raw_value"] } serde_json = { workspace = true, features = ["raw_value"] }
tauri = { workspace = true, features = ["devtools", "protocol-asset"] } tauri = { workspace = true, features = ["devtools", "protocol-asset"] }
tauri-plugin-clipboard-manager = "2.2.2" tauri-plugin-clipboard-manager = "2.2.2"
tauri-plugin-dialog = "2.2.0" tauri-plugin-dialog = { workspace = true }
tauri-plugin-fs = "2.2.0" tauri-plugin-fs = "2.2.0"
tauri-plugin-log = { version = "2.3.1", features = ["colored"] } tauri-plugin-log = { version = "2.3.1", features = ["colored"] }
tauri-plugin-opener = "2.2.6" tauri-plugin-opener = "2.2.6"
@@ -87,6 +87,7 @@ serde = "1.0.219"
serde_json = "1.0.140" serde_json = "1.0.140"
tauri = "2.4.1" tauri = "2.4.1"
tauri-plugin = "2.1.1" tauri-plugin = "2.1.1"
tauri-plugin-dialog = "2.2.0"
tauri-plugin-shell = "2.2.1" tauri-plugin-shell = "2.2.1"
tokio = "1.44.2" tokio = "1.44.2"
thiserror = "2.0.12" thiserror = "2.0.12"

View File

@@ -17,7 +17,8 @@ sea-query-rusqlite = { version = "0.7.0", features = ["with-chrono"] }
serde = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true } serde_json = { workspace = true }
sha2 = "0.10.9" sha2 = "0.10.9"
tauri = { workspace = true } tauri = { workspace = true}
tauri-plugin-dialog = { workspace = true }
thiserror = "2.0.11" thiserror = "2.0.11"
tokio = { workspace = true } tokio = { workspace = true }
ts-rs = { workspace = true, features = ["chrono-impl", "serde-json-impl"] } ts-rs = { workspace = true, features = ["chrono-impl", "serde-json-impl"] }

View File

@@ -20,6 +20,9 @@ pub enum Error {
#[error("Model error: {0}")] #[error("Model error: {0}")]
GenericError(String), GenericError(String),
#[error("DB Migration Failed: {0}")]
MigrationError(String),
#[error("No base environment for {0}")] #[error("No base environment for {0}")]
MissingBaseEnvironment(String), MissingBaseEnvironment(String),

View File

@@ -1,22 +1,24 @@
use crate::commands::*; use crate::commands::*;
use crate::migrate::migrate_db;
use crate::query_manager::QueryManager; use crate::query_manager::QueryManager;
use crate::util::ModelChangeEvent; use crate::util::ModelChangeEvent;
use log::error;
use r2d2::Pool; use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager; use r2d2_sqlite::SqliteConnectionManager;
use std::fs::create_dir_all; use std::fs::create_dir_all;
use std::time::Duration; use std::time::Duration;
use tauri::async_runtime::Mutex; use tauri::async_runtime::Mutex;
use tauri::plugin::TauriPlugin; use tauri::plugin::TauriPlugin;
use tauri::{generate_handler, Emitter, Manager, Runtime}; use tauri::{Emitter, Manager, Runtime, generate_handler};
use tauri_plugin_dialog::{DialogExt, MessageDialogKind};
use tokio::sync::mpsc; use tokio::sync::mpsc;
use crate::migrate::must_migrate_db;
mod commands; mod commands;
mod connection_or_tx; mod connection_or_tx;
mod migrate;
pub mod db_context; pub mod db_context;
pub mod error; pub mod error;
mod migrate;
pub mod models; pub mod models;
pub mod queries; pub mod queries;
pub mod query_manager; pub mod query_manager;
@@ -57,7 +59,15 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
.build(manager) .build(manager)
.unwrap(); .unwrap();
must_migrate_db(app_handle.app_handle(), &pool).expect("Failed to run migrations"); if let Err(e) = migrate_db(app_handle.app_handle(), &pool) {
error!("Failed to run database migration {e:?}");
app_handle
.dialog()
.message(e.to_string())
.kind(MessageDialogKind::Error)
.blocking_show();
return Err(Box::from(e.to_string()));
};
app_handle.manage(SqliteConnection::new(pool.clone())); app_handle.manage(SqliteConnection::new(pool.clone()));

View File

@@ -1,5 +1,6 @@
use crate::error::Error::MigrationError;
use crate::error::Result; use crate::error::Result;
use log::{error, info}; use log::info;
use r2d2::Pool; use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager; use r2d2_sqlite::SqliteConnectionManager;
use rusqlite::{OptionalExtension, TransactionBehavior, params}; use rusqlite::{OptionalExtension, TransactionBehavior, params};
@@ -10,7 +11,7 @@ use std::result::Result as StdResult;
use tauri::path::BaseDirectory; use tauri::path::BaseDirectory;
use tauri::{AppHandle, Manager, Runtime}; use tauri::{AppHandle, Manager, Runtime};
pub(crate) fn must_migrate_db<R: Runtime>( pub(crate) fn migrate_db<R: Runtime>(
app_handle: &AppHandle<R>, app_handle: &AppHandle<R>,
pool: &Pool<SqliteConnectionManager>, pool: &Pool<SqliteConnectionManager>,
) -> Result<()> { ) -> Result<()> {
@@ -54,9 +55,13 @@ pub(crate) fn must_migrate_db<R: Runtime>(
match run_migration(entry.path().as_path(), &mut tx) { match run_migration(entry.path().as_path(), &mut tx) {
Ok(_) => tx.commit()?, Ok(_) => tx.commit()?,
Err(e) => { Err(e) => {
error!("Failed to apply migration {:?} {e:?}", entry.path().file_name()); let msg = format!(
"{} failed with {}",
entry.path().file_name().unwrap().to_str().unwrap(),
e.to_string()
);
tx.rollback()?; tx.rollback()?;
return Err(e); return Err(MigrationError(msg));
} }
}; };
} }