every-day-things/citadel

Create Calibre-compat. library when none is detected

AlphaJack opened this issue · 1 comments

Re-written by @phildenhoff. Original issue desc. below.

When a user selects a folder for their library that is not a pre-existing Calibre library (e.g. no metadata.db file),

  • Confirm that is the correct location
  • If so, do they want to create a new library? Warn that that will add many folders & a database file at that location
  • If not, select a new folder.

If Citadel cannot operate without a Calibre library already in place, can it check for the Calibre database at the folder selection step?

Otherwise, adding a book to an empty folder crashes the app:

RUST_BACKTRACE=full /usr/bin/citadel

thread 'main' panicked at src/libs/calibre/mod.rs:187:17:
Could not find database at /home/jack/Citadel/
stack backtrace:
   0:     0x5639e2268c9c - std::backtrace_rs::backtrace::libunwind::trace::he0644f4189ae2429
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/../../backtrace/src/backtrace/libunwind.rs:104:5
   1:     0x5639e2268c9c - std::backtrace_rs::backtrace::trace_unsynchronized::h9d17fc782d3b981a
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x5639e2268c9c - std::sys_common::backtrace::_print_fmt::hb438557330fe04dd
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/sys_common/backtrace.rs:67:5
   3:     0x5639e2268c9c - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hfbaa40019107bf73
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/sys_common/backtrace.rs:44:22
   4:     0x5639e2299230 - core::fmt::rt::Argument::fmt::hb051b4144eaf7ba9
                               at /build/rust/src/rustc-1.75.0-src/library/core/src/fmt/rt.rs:142:9
   5:     0x5639e2299230 - core::fmt::write::h09ae4ee704823005
                               at /build/rust/src/rustc-1.75.0-src/library/core/src/fmt/mod.rs:1120:17
   6:     0x5639e226507d - std::io::Write::write_fmt::h2f754c40a62d69e7
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/io/mod.rs:1762:15
   7:     0x5639e2268a85 - std::sys_common::backtrace::_print::h5aa33cefb716154f
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/sys_common/backtrace.rs:47:5
   8:     0x5639e2268a85 - std::sys_common::backtrace::print::hba7db713d2ca6e46
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/sys_common/backtrace.rs:34:9
   9:     0x5639e226a2d3 - std::panicking::default_hook::{{closure}}::hdecc168c96eda73a
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:272:22
  10:     0x5639e226a00a - std::panicking::default_hook::h094baec9e5d8cab2
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:292:9
  11:     0x5639e226a805 - std::panicking::rust_panic_with_hook::h1d7664437b07c6b2
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:779:13
  12:     0x5639e226a6ee - std::panicking::begin_panic_handler::{{closure}}::hcf3241a5a930cf68
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:657:13
  13:     0x5639e2269156 - std::sys_common::backtrace::__rust_end_short_backtrace::h5bffafd462cab801
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/sys_common/backtrace.rs:170:18
  14:     0x5639e226a472 - rust_begin_unwind
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:645:5
  15:     0x5639e19f6ab5 - core::panicking::panic_fmt::h45860aff82e9ff99
                               at /build/rust/src/rustc-1.75.0-src/library/core/src/panicking.rs:72:14
  16:     0x5639e1ad9521 - citadel_rs::libs::calibre::add_book_to_db_by_metadata::h091d8d1888d3ca69
  17:     0x5639e1b64983 - citadel_rs::run_tauri_backend::{{closure}}::h3bb29e5111b22700
  18:     0x5639e1b631c1 - <tauri::plugin::TauriPlugin<R,C> as tauri::plugin::Plugin<R>>::extend_api::h39fc29458d96579b
  19:     0x5639e1b514ed - tauri::plugin::PluginStore<R>::extend_api::h9168bad0d72111a2
  20:     0x5639e1a6fb8c - tauri::manager::WindowManager<R>::extend_api::h244fd2d23d749935
  21:     0x5639e1b56250 - tauri::window::Window<R>::on_message::hd9491f566b821a6b
  22:     0x5639e1a724a7 - tauri::manager::WindowManager<R>::prepare_ipc_handler::{{closure}}::h01dfecb7134b3895
  23:     0x5639e1b2cf2a - tauri_runtime_wry::create_ipc_handler::{{closure}}::h7bde2fd2d1179594
  24:     0x5639e1a78420 - <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call::h20407a0158c08f3a
  25:     0x5639e1eb4353 - <O as webkit2gtk::auto::user_content_manager::UserContentManagerExt>::connect_script_message_received::script_message_received_trampoline::h72b90c7c1777d1b2
  26:     0x7f7e4fbb26c0 - g_closure_invoke
  27:     0x7f7e4fbe0a36 - <unknown>
  28:     0x7f7e4fbd1a42 - <unknown>
  29:     0x7f7e4fbd1c77 - g_signal_emit_valist
  30:     0x7f7e4fbd1d34 - g_signal_emit
  31:     0x7f7e540e5d88 - <unknown>
  32:     0x7f7e53caf98e - <unknown>
  33:     0x7f7e53f916f5 - <unknown>
  34:     0x7f7e54070dce - <unknown>
  35:     0x7f7e53f86a8e - <unknown>
  36:     0x7f7e53f8abb2 - <unknown>
  37:     0x7f7e51ad2aab - <unknown>
  38:     0x7f7e51ad2b91 - <unknown>
  39:     0x7f7e4faabf69 - <unknown>
  40:     0x7f7e4fb0a367 - <unknown>
  41:     0x7f7e4faaa162 - g_main_context_iteration
  42:     0x7f7e521ed3c7 - gtk_main_iteration_do
  43:     0x5639e1eeee3d - gtk::auto::functions::main_iteration_do::hf7f1f4b33400a7c3
  44:     0x5639e1b7b1ad - glib::main_context::<impl glib::auto::main_context::MainContext>::with_thread_default::h451a5aa60667354f
  45:     0x5639e1b3de52 - tao::platform_impl::platform::event_loop::EventLoop<T>::run::hc1de31bbe5167cca
  46:     0x5639e1b6256d - <tauri_runtime_wry::Wry<T> as tauri_runtime::Runtime<T>>::run::h948abacff27924ed
  47:     0x5639e1a7cbb8 - citadel_rs::run_tauri_backend::hfba7896320e1d756
  48:     0x5639e1bc352f - <tokio::task::local::RunUntil<T> as core::future::future::Future>::poll::ha5cedacb30465c30
  49:     0x5639e1bdd11c - <core::pin::Pin<P> as core::future::future::Future>::poll::h5b4f109d65dda040
  50:     0x5639e1bc227c - tokio::runtime::scheduler::current_thread::Context::enter::hcd1680d270807e31
  51:     0x5639e1a4e0fc - tokio::runtime::context::set_scheduler::hbb6d62a0de494b81
  52:     0x5639e1bc186f - tokio::runtime::scheduler::current_thread::CurrentThread::block_on::h1ef579b3b0127ac9
  53:     0x5639e1bdcf8d - tokio::runtime::runtime::Runtime::block_on::h1417fa88ebfcd082
  54:     0x5639e1a7d895 - citadel_rs::main::h5204abaf2ee96bfb
  55:     0x5639e1b10493 - std::sys_common::backtrace::__rust_begin_short_backtrace::hce4b60bab80bff90
  56:     0x5639e1b912b9 - std::rt::lang_start::{{closure}}::hf4fd96fb54286a84
  57:     0x5639e225dbed - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h6e58cd4b3aa0cedc
                               at /build/rust/src/rustc-1.75.0-src/library/core/src/ops/function.rs:284:13
  58:     0x5639e225dbed - std::panicking::try::do_call::h1d63a6ddcddbf3d7
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:552:40
  59:     0x5639e225dbed - std::panicking::try::ha98263394816949f
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:516:19
  60:     0x5639e225dbed - std::panic::catch_unwind::hc08a17c58416f4cc
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panic.rs:142:14
  61:     0x5639e225dbed - std::rt::lang_start_internal::{{closure}}::h8a6385fe0d26a9d5
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/rt.rs:148:48
  62:     0x5639e225dbed - std::panicking::try::do_call::h6b4548ddcceb66f1
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:552:40
  63:     0x5639e225dbed - std::panicking::try::ha4d76d1974f7f45a
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panicking.rs:516:19
  64:     0x5639e225dbed - std::panic::catch_unwind::h691bb3d050a579da
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/panic.rs:142:14
  65:     0x5639e225dbed - std::rt::lang_start_internal::h1630c9ed041f86ee
                               at /build/rust/src/rustc-1.75.0-src/library/std/src/rt.rs:148:20
  66:     0x5639e1b912ae - std::rt::lang_start::h81cf3f1050ed8f71
  67:     0x7f7e4f158cd0 - <unknown>
  68:     0x7f7e4f158d8a - __libc_start_main
  69:     0x5639e19f7495 - _start
  70:                0x0 - <unknown>

A little warning that you're selected folder isn't valid could work, but I'd really like to get to a place where we can generate Calibre databases from scratch.

That'll take a bit more fiddling to figure out what Calibre considers a valid database. Right now, there is a DB generation script, but if Calibre opens the generated database it deletes the file & starts from scratch.

Another option is to skip that step (for now) and load a minimal Calibre-created database into the binary. Any time we need a new DB, we copy that out. Honestly, that might be preferable to creating it "from scratch", since I believe running the migration script requires the diesel CLI. But maybe we could get around diesel by not creating the DB by running migrations? Not sure.


In terms of the overall experience of "the app crashes when something weird happens" — that is definitely bad. I'd like to catch those exceptions as Results instead of panicking, and this is a great example of a case I missed. However, Citadel is very new and I'm fine with balancing instability with getting features out, so do expect the occasional crash like this.