app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit c4d4c3571826963ac56a136ec7f0ced1bd553c29
parent 4abf87f4b0af09f7451c27f580ad3830d60e0a3a
Author: triesap <tyson@radroots.org>
Date:   Fri, 20 Mar 2026 18:47:54 +0000

web: avoid startup panics on missing dom

Diffstat:
Mcrates/web/src/lib.rs | 71+++++++++++++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 49 insertions(+), 22 deletions(-)

diff --git a/crates/web/src/lib.rs b/crates/web/src/lib.rs @@ -166,6 +166,50 @@ impl RadrootsAppBackend for WebBackend { } #[cfg(target_arch = "wasm32")] +fn loading_text_element() -> Option<web_sys::Element> { + let window = web_sys::window()?; + let document = window.document()?; + document.get_element_by_id("loading_text") +} + +#[cfg(target_arch = "wasm32")] +fn clear_loading_text() { + if let Some(loading_text) = loading_text_element() { + loading_text.remove(); + } +} + +#[cfg(target_arch = "wasm32")] +fn show_loading_failure() { + if let Some(loading_text) = loading_text_element() { + loading_text.set_inner_html("<p>failed to start radroots app</p>"); + } +} + +#[cfg(target_arch = "wasm32")] +async fn launch_app() -> Result<(), String> { + let web_options = eframe::WebOptions::default(); + let window = web_sys::window().ok_or_else(|| "window unavailable".to_owned())?; + let document = window + .document() + .ok_or_else(|| "document unavailable".to_owned())?; + let canvas = document + .get_element_by_id("radroots_app_canvas") + .ok_or_else(|| "radroots_app_canvas missing".to_owned())? + .dyn_into::<web_sys::HtmlCanvasElement>() + .map_err(|_| "radroots_app_canvas is not a canvas element".to_owned())?; + + eframe::WebRunner::new() + .start( + canvas, + web_options, + Box::new(|_cc| Ok(Box::new(RadrootsApp::new(Box::new(WebBackend::new()))))), + ) + .await + .map_err(|err| format!("failed to start radroots app: {err:?}")) +} + +#[cfg(target_arch = "wasm32")] pub fn launch() { let log_level = if cfg!(debug_assertions) { log::LevelFilter::Info @@ -175,28 +219,11 @@ pub fn launch() { let _ = eframe::WebLogger::init(log_level); wasm_bindgen_futures::spawn_local(async { - let web_options = eframe::WebOptions::default(); - let window = web_sys::window().expect("window"); - let document = window.document().expect("document"); - let canvas = document - .get_element_by_id("radroots_app_canvas") - .expect("radroots_app_canvas") - .dyn_into::<web_sys::HtmlCanvasElement>() - .expect("canvas"); - - let result = eframe::WebRunner::new() - .start( - canvas, - web_options, - Box::new(|_cc| Ok(Box::new(RadrootsApp::new(Box::new(WebBackend::new()))))), - ) - .await; - - if let Some(loading_text) = document.get_element_by_id("loading_text") { - if result.is_ok() { - loading_text.remove(); - } else { - loading_text.set_inner_html("<p>failed to start radroots app</p>"); + match launch_app().await { + Ok(()) => clear_loading_text(), + Err(err) => { + log::error!("{err}"); + show_loading_failure(); } } });