Commit eb9006e7 authored by Simon Goller's avatar Simon Goller Committed by Rahix
Browse files

Introduce panic screen

If something panics - which should never happen - the error message
and the stack trace is now displayed in the browser window.
parent 089811d2
......@@ -49,6 +49,8 @@ features = [
"SvgElement",
"CssStyleDeclaration",
"KeyboardEvent",
"HtmlCollection",
"HtmlAnchorElement",
]
[profile.dev]
......
use core::panic;
use js_sys;
use wasm_bindgen::prelude::*;
pub mod angel_shifts;
......@@ -13,9 +15,47 @@ pub mod svg_loader;
pub mod systems;
pub mod utils;
#[wasm_bindgen]
extern "C" {
type Error;
#[wasm_bindgen(constructor)]
fn new() -> Error;
#[wasm_bindgen(structural, method, getter)]
fn stack(error: &Error) -> String;
}
pub fn error_hook(panic_info: &panic::PanicInfo) {
utils::get_first_element_by_class_name::<web_sys::HtmlElement>("crash-screen")
.unwrap()
.style()
.set_property("display", "block")
.unwrap();
let mut message = panic_info.to_string();
message.push_str("\n\nStacktrace:\n");
let e = Error::new();
let stack = e.stack();
message.push_str(&stack);
let url_encoded_message = js_sys::encode_uri_component(&format!("```\n{}\n```", &message))
.as_string()
.unwrap();
let bugreport_link = format!("https://gitlab.muc.ccc.de/engel-simulator-2020/game/-/issues/new?issue[title]=Bug%20Report&issue[description]={}", url_encoded_message);
utils::get_first_element_by_class_name::<web_sys::HtmlAnchorElement>(
"crash-screen-bugreport-link",
)
.unwrap()
.set_href(&bugreport_link);
utils::get_first_element_by_class_name::<web_sys::HtmlElement>("crash-screen-error")
.unwrap()
.set_inner_html(&message);
}
#[wasm_bindgen]
pub fn start() -> Result<(), JsValue> {
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
std::panic::set_hook(Box::new(error_hook));
utils::update_version_info();
gamestate::StateMachine::launch(states::MainMenuState::new());
Ok(())
......
......@@ -73,6 +73,15 @@ pub fn get_element_by_id<T: wasm_bindgen::JsCast>(id: &str) -> anyhow::Result<T>
.map_err(|_| anyhow::anyhow!("cannot cast into expected type"))
}
pub fn get_first_element_by_class_name<T: wasm_bindgen::JsCast>(class: &str) -> anyhow::Result<T> {
document()
.get_elements_by_class_name(class)
.item(0)
.with_context(|| format!("cannot find element {:?}", class))?
.dyn_into::<T>()
.map_err(|_| anyhow::anyhow!("cannot cast into expected type"))
}
pub fn event_handler<F, S>(setter: S, fun: F)
where
F: FnMut(wasm_bindgen::JsValue) + 'static,
......
......@@ -135,6 +135,16 @@
</g>
</svg>
</div>
<div class="crash-screen">
<div class="crash-screen-title">For Heaven's Sake! It crashed!</div>
<div class="reload-button">
<button onclick="location.reload()">Restart Game</button>
<a class="crash-screen-bugreport-link" href="https://gitlab.muc.ccc.de/engel-simulator-2020/game/-/issues/new">Report bug</a>
</div>
<div class="crash-screen-body">
<pre class="crash-screen-error"></pre>
</div>
</div>
<script src="./bundle.js"></script>
</body>
</html>
......@@ -189,3 +189,33 @@ div.game {
}
}
}
div.crash-screen {
display: none;
position: absolute;
left: 100px;
right: 100px;
top: 100px;
bottom: 100px;
background: #000;
overflow: auto;
div.crash-screen-title {
font-family: "Orbitron";
font-weight: 900;
fill: #ffffff;
font-size: 72pt;
color: white;
}
pre.crash-screen-error {
font-family: monospace;
fill: #ffffff;
font-size: 12pt;
color: red;
}
a.crash-screen-bugreport-link {
color: #05b9ec;
padding-left: 2em;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment