Skip to content

Commit

Permalink
fix(web): gracefully return an error if app fails to start
Browse files Browse the repository at this point in the history
  • Loading branch information
ten3roberts committed Sep 28, 2023
1 parent 768d108 commit 0c14290
Showing 1 changed file with 35 additions and 24 deletions.
59 changes: 35 additions & 24 deletions web/client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,9 @@ use ambient_ui_native::{
element::{ElementComponentExt, Group},
WindowSized,
};
use anyhow::Context;
use app::MainApp;
use tracing_subscriber::{
filter::{LevelFilter, Targets},
prelude::*,
registry,
};
use tracing_subscriber::{filter::Targets, prelude::*, registry};
use tracing_web::MakeConsoleWriter;
use wasm_bindgen::prelude::*;

Expand All @@ -30,30 +27,52 @@ static APP_CONTROL: OnceLock<flume::Sender<WindowCtl>> = OnceLock::new();
/// backwards and forwards compatibility when new fields are added to the settings object in a
/// "best fit" approach, similar to the `settings` in the LanguageServerProtocol spec.
pub struct Settings {
#[serde(default = "default_true")]
enable_logging: bool,
#[serde(default = "default_true")]
enable_panic_hook: bool,
#[serde(default)]
allow_version_mismatch: bool,
log_filter: Option<String>,
#[serde(default = "default_filter")]
log_filter: String,
#[serde(default)]
debugger: bool,
}

fn default_filter() -> String {
"info".into()
}

fn default_true() -> bool {
true
}

#[wasm_bindgen]
/// Starts execution of the ambient client and connects to the specified URL
///
/// TODO: The `MainApp` setup will move to an Ambient package and this will only load the runtime
pub async fn start(target: Option<web_sys::HtmlElement>, server_url: String, settings: JsValue) {
let settings: Settings =
serde_wasm_bindgen::from_value(settings).expect("settings can be parsed from object");
///
/// Finishes once the app has been built and initialized
pub async fn start(
target: Option<web_sys::HtmlElement>,
server_url: String,
settings: JsValue,
) -> Result<(), JsValue> {
let settings: Settings = serde_wasm_bindgen::from_value(settings)?;

init(&settings).expect("Failed to initialize ambient");
init(&settings)
.context("Failed to initialize ambient")
.map_err(|e| format!("{e:?}"))?;

if let Err(err) = run(target, server_url, settings).await {
tracing::error!("{err:?}")
}
run(target, server_url, settings)
.await
.map_err(|e| format!("{e:?}"))?;

Ok(())
}

/// Initialize ambient
fn init(settings: &Settings) -> Result<(), JsValue> {
fn init(settings: &Settings) -> anyhow::Result<()> {
if settings.enable_logging {
let fmt_layer = tracing_subscriber::fmt::layer()
.with_ansi(true) // Only partially supported, but works on Chrome
Expand All @@ -62,13 +81,8 @@ fn init(settings: &Settings) -> Result<(), JsValue> {

let filter = settings
.log_filter
.as_ref()
.map(|v| {
v.parse::<Targets>()
.map_err(|_| JsValue::from("Failed to parse filtering directive"))
})
.transpose()?
.unwrap_or_else(|| Targets::new().with_default(LevelFilter::INFO));
.parse::<Targets>()
.context("Failed to parse filtering directive")?;

registry().with(filter).with(fmt_layer).init();
}
Expand Down Expand Up @@ -114,7 +128,6 @@ async fn run(
use ambient_sys::timer::TimerWheel;
ambient_sys::task::spawn(TimerWheel::new().start());

use anyhow::Context;
let mut app = App::builder()
.ui_renderer(true)
.parent_element(target)
Expand All @@ -123,8 +136,6 @@ async fn run(
.await
.context("Failed to build app")?;

tracing::info!("Finished building app");

let world = &mut app.world;

Group(vec![
Expand Down

0 comments on commit 0c14290

Please sign in to comment.