{"record":{"id":"5a0e96f58b853bd0","repo":"linebender/druid","slug":"failed-to-request-animation-frame","errorCode":null,"errorMessage":"Failed to request animation frame","messagePattern":"Failed to request animation frame","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"druid-shell/src/backend/web/window.rs","lineNumber":478,"sourceCode":"            canvas,\n            canvas_size,\n            context,\n            invalid: RefCell::new(Region::EMPTY),\n            click_counter: ClickCounter::default(),\n            active_text_input: Cell::new(None),\n            rendering_soon: Cell::new(false),\n        });\n\n        setup_web_callbacks(&window);\n\n        // Register the scale & size with the window handler.\n        let wh = window.clone();\n        window\n            .request_animation_frame(move || {\n                wh.handler.borrow_mut().scale(scale);\n                wh.handler.borrow_mut().size(size_dp);\n            })\n            .expect(\"Failed to request animation frame\");\n\n        let handle = WindowHandle(Rc::downgrade(&window));\n\n        window.handler.borrow_mut().connect(&handle.clone().into());\n\n        Ok(handle)\n    }\n}\n\nimpl WindowHandle {\n    pub fn show(&self) {\n        self.render_soon();\n    }\n\n    pub fn resizable(&self, _resizable: bool) {\n        warn!(\"resizable unimplemented for web\");\n    }\n","sourceCodeStart":460,"sourceCodeEnd":496,"githubUrl":"https://github.com/linebender/druid/blob/0f8b1195e4e073f9597f2865299c3d18f8e4005f/druid-shell/src/backend/web/window.rs#L460-L496","documentation":"Panic from `.expect()` when the JS `window.requestAnimationFrame()` call, made while building a `Window` in the web backend, throws or the browser rejects the callback registration. The library uses an animation frame to deliver the initial scale/size events to the handler; without it the new window would never learn its geometry, so failure is treated as fatal to `build`.","triggerScenarios":"`WindowBuilder::build()` (web/wasm32 target) when `requestAnimationFrame` throws — e.g. the page is being torn down, the code runs outside a browser window context (worker/jsdom/testing harness), or the browser refuses callback registration during page unload/navigation.","commonSituations":"Testing a druid/wasm app under Node or jsdom where `requestAnimationFrame` is unimplemented, embedding the canvas in an iframe that is removed during startup, or triggering window creation during `beforeunload`/`visibility: hidden` shutdown.","solutions":["Ensure `build()` runs from a real browser window context after the DOM/canvas is ready (e.g. inside `requestAnimationFrame`/`onload`), not in a worker or during unload","Provide a `requestAnimationFrame` polyfill when testing under Node/jsdom (e.g. raf polyfill package)","Check the browser console for the underlying JS exception; fix the page lifecycle issue it reports","Patch the app to call `build()` after `document.visibilitychange` indicates the page is visible"],"exampleFix":"// before\nlet window = WindowBuilder::new(app).build().expect(\"build failed\"); // panics here in jsdom\n// after (ensure browser-like env first)\nif window web_sys::window().and_then(|w| w.request_animation_frame(cb)) .is_none() {\n    panic!(\"requestAnimationFrame unavailable: run in a real browser environment\");\n}\nlet window = WindowBuilder::new(app).build().expect(\"build failed\");","handlingStrategy":"try-catch","validationCode":"// Ensure a real browser context exists before building windows\nfn browser_ready() -> bool {\n    web_sys::window()\n        .map(|w| w.document().is_some())\n        .unwrap_or(false)\n}","typeGuard":"fn has_window() -> bool {\n    web_sys::window().is_some()\n}","tryCatchPattern":"// Panics cannot be caught across wasm normally; validate before build:\nif !browser_ready() {\n    console_error(\"window.build called outside a browser window context\");\n    return; // abort startup instead of panicking inside build()\n}\nlet handle = WindowBuilder::new(app).build().expect(\"build failed\");","preventionTips":["Call build() only from browser UI events, never from workers or unload handlers","Add a rAF polyfill when running wasm tests under Node/jsdom","Wait for DOMContentLoaded/canvas mount before constructing windows","Watch the browser console for JS exceptions during startup"],"tags":["web","wasm","request-animation-frame","browser"],"backgroundTag":"request-animation-frame-failed","analyzedSha":"0f8b1195e4e073f9597f2865299c3d18f8e4005f","analyzedAt":"2026-09-10T14:27:34.582Z","contentChangedAt":"2026-09-10T14:27:34.582Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}