1469: Handle winit exception in web to avoid breaking async executor r=grovesNL a=Frizi

This is a continuation of https://github.com/gfx-rs/wgpu-rs/pull/923.

I'd still like to fix this on our end, even if the real underlying issue is in winit. The fix is small, and we can migrate to the proper winit solution once it exists. In the mean time, we can continue working on improving webgl support without a major blocker.

Co-authored-by: Frizi <frizi09@gmail.com>
This commit is contained in:
bors[bot]
2021-06-03 11:25:46 +00:00
committed by GitHub
2 changed files with 23 additions and 2 deletions

View File

@@ -357,10 +357,31 @@ pub fn run<E: Example>(title: &str) {
#[cfg(target_arch = "wasm32")]
pub fn run<E: Example>(title: &str) {
use wasm_bindgen::{prelude::*, JsCast};
let title = title.to_owned();
wasm_bindgen_futures::spawn_local(async move {
let setup = setup::<E>(&title).await;
start::<E>(setup);
let start_closure = Closure::once_into_js(move || start::<E>(setup));
// make sure to handle JS exceptions thrown inside start.
// Otherwise wasm_bindgen_futures Queue would break and never handle any tasks again.
// This is required, because winit uses JS exception for control flow to escape from `run`.
if let Err(error) = call_catch(&start_closure) {
let is_control_flow_exception = error.dyn_ref::<js_sys::Error>().map_or(false, |e| {
e.message().includes("Using exceptions for control flow", 0)
});
if !is_control_flow_exception {
web_sys::console::error_1(&error);
}
}
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(catch, js_namespace = Function, js_name = "prototype.call.call")]
fn call_catch(this: &JsValue) -> Result<(), JsValue>;
}
});
}

View File

@@ -1940,7 +1940,7 @@ impl fmt::Debug for ErrorSinkRaw {
}
fn default_error_handler(err: crate::Error) {
eprintln!("wgpu error: {}\n", err);
log::error!("wgpu error: {}\n", err);
panic!("Handling wgpu errors as fatal by default");
}