Skip to content

Commit 4b0ac92

Browse files
stevekwon211claude
andcommitted
fix(web): ignore winit's control-flow exception on WASM init
The live demo showed "Failed to load WebAssembly bundle" with the message "Using exceptions for control flow, don't mind me. This isn't actually an error!". That exception is winit's documented mechanism: on wasm32, EventLoop::run() never returns, so it throws a JS exception to unwind the Rust stack and hand control to the browser's event loop. The app is fully running behind it — our try/catch was just mis-classifying the benign unwind as a fatal error. index.html now filters that specific exception (matches "control flow" / "isn't actually an error") and reveals the canvas instead of showing the error overlay. Genuine init failures still surface. No WASM rebuild needed — pure JS-side fix. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent f32bc4b commit 4b0ac92

1 file changed

Lines changed: 27 additions & 11 deletions

File tree

web/index.html

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,35 @@
6060

6161
<script type="module">
6262
import init from './pkg/slintcn-showcase.js';
63-
try {
64-
await init();
65-
// ui.run() returned (registers handlers, browser drives the loop).
66-
// Hide the loader so Slint's canvas is visible.
63+
64+
function reveal() {
6765
document.getElementById('loader').classList.add('hidden');
68-
} catch (err) {
69-
const loader = document.getElementById('loader');
70-
loader.innerHTML = `
71-
<div class="brand">slintcn</div>
72-
<div class="err">Failed to load WebAssembly bundle.\n${err && err.stack || err}</div>
73-
`;
74-
console.error('slintcn init failed:', err);
7566
}
67+
68+
function isWinitControlFlow(err) {
69+
// winit hands control to the browser from EventLoop::run() by
70+
// THROWING a JS exception that unwinds the Rust stack. It's not a
71+
// failure — the app is already running behind it. The message is
72+
// winit's own: "Using exceptions for control flow…".
73+
const msg = (err && (err.message || err.toString())) || '';
74+
return msg.includes('control flow') || msg.includes("isn't actually an error");
75+
}
76+
77+
init()
78+
.then(reveal)
79+
.catch((err) => {
80+
if (isWinitControlFlow(err)) {
81+
// Expected. The Slint canvas is live; just show it.
82+
reveal();
83+
return;
84+
}
85+
const loader = document.getElementById('loader');
86+
loader.innerHTML = `
87+
<div class="brand">slintcn</div>
88+
<div class="err">Failed to load WebAssembly bundle.\n${(err && err.stack) || err}</div>
89+
`;
90+
console.error('slintcn init failed:', err);
91+
});
7692
</script>
7793
</body>
7894
</html>

0 commit comments

Comments
 (0)