{"record":{"id":"df3f4b9f86d40caa","repo":"slint-ui/slint","slug":"x","errorCode":null,"errorMessage":"{x:?}","messagePattern":"\\{x:\\?\\}","errorType":"exception","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"tools/lsp/wasm_main.rs","lineNumber":477,"sourceCode":"        let mut ctx = self.ctx.lock().await;\n        let result = self\n            .rh\n            .handle_request(method, params, &mut ctx)\n            .map_err(|e| JsError::new(&e.to_string()))?;\n        Ok(result)\n    }\n\n    #[wasm_bindgen]\n    pub async fn reload_config(&self) -> JsResult<()> {\n        let mut ctx = self.ctx.lock().await;\n        language::load_configuration(&mut ctx).await.map_err(|e| JsError::new(&e.to_string()))\n    }\n}\n\nasync fn load_file(path: String, load_file: &Function) -> std::io::Result<String> {\n    let string_promise = load_file\n        .call1(&JsValue::UNDEFINED, &path.into())\n        .map_err(|x| std::io::Error::new(ErrorKind::Other, format!(\"{x:?}\")))?;\n    let string_future = wasm_bindgen_futures::JsFuture::from(js_sys::Promise::from(string_promise));\n    let js_value =\n        string_future.await.map_err(|e| std::io::Error::new(ErrorKind::Other, format!(\"{e:?}\")))?;\n    return Ok(js_value.as_string().unwrap_or_default());\n}\n\n// Use a JSON friendly representation to avoid using ES maps instead of JS objects.\nfn to_value<T: serde::Serialize + ?Sized>(\n    value: &T,\n) -> std::result::Result<wasm_bindgen::JsValue, serde_wasm_bindgen::Error> {\n    value.serialize(&serde_wasm_bindgen::Serializer::json_compatible())\n}\n","sourceCodeStart":459,"sourceCodeEnd":490,"githubUrl":"https://github.com/slint-ui/slint/blob/bb937076de3f7919766c1f25e2e969367cf77e9a/tools/lsp/wasm_main.rs#L459-L490","documentation":"When the LSP server compiled to WASM asks the injected JavaScript `load_file` callback to fetch a file's contents, any JS-side rejection of that call is converted into a std::io::Error whose message is the Debug formatting of the wasm_bindgen JsValue. The library throws it because it cannot proceed loading the requested URI without the file content the host JS environment failed to provide. The message is opaque (`JsValue(...)` debug output) because the Rust side cannot know the JS error's structure.","triggerScenarios":"Calling LSP operations that need file contents (e.g. opening a document, diagnostics) when the injected `load_file` JS function rejects: the fetch/XHR in the browser fails, the JS callback throws, or it returns a non-Promise value.","commonSituations":"Serving the WASM LSP from a page where the resource path is wrong (404), CORS blocks the fetch, the file server is down, or the host page supplies a broken/misbehaving `load_file` callback (e.g. returns a rejected Promise or undefined).","solutions":["Inspect the browser console/network tab to find the real JS error behind the debug-formatted JsValue (404, CORS, network).","Verify the URI passed by the LSP client maps to a URL your `load_file` callback can fetch from the web page origin.","Fix the host JS `load_file` implementation to return a Promise resolving to the file's UTF-8 string and to propagate readable error messages.","Serve the WASM bundle and files from the same origin or configure CORS headers on the file server.","Retry the request after fixing connectivity; transient network failures also surface here."],"exampleFix":"// before (host JS, throws opaque rejection)\nconst load_file = (path) => fetch(path);\n// after\nconst load_file = async (path) => {\n  const res = await fetch(path);\n  if (!res.ok) throw new Error(`failed to load ${path}: HTTP ${res.status}`);\n  return res.text();\n};","handlingStrategy":"try-catch","validationCode":"// JS host side, before registering the callback\nasync function validateLoadFile(path) {\n  const res = await fetch(path, { method: 'HEAD' });\n  if (!res.ok) throw new Error(`unreachable: ${path} -> ${res.status}`);\n}","typeGuard":"// JS host side\nfunction isPromise(v) { return v && typeof v.then === 'function'; }","tryCatchPattern":"// JS host side wrapping the callback given to the WASM LSP\nconst load_file = async (path) => {\n  try {\n    const res = await fetch(path);\n    if (!res.ok) throw new Error(`HTTP ${res.status}`);\n    return await res.text();\n  } catch (err) {\n    console.error('load_file failed for', path, err); // read this, not the Rust Debug output\n    throw err;\n  }\n};","preventionTips":["Serve files same-origin or configure CORS before using the WASM LSP.","Always return a Promise<string> from the load_file callback.","Log JS-side errors verbosely; the Rust error only shows Debug(JsValue).","Test LSP startup against the real served paths, including 404 cases.","Monitor the network tab during LSP operation in dev tools."],"tags":["wasm","javascript","lsp","file-loading","debug-format"],"backgroundTag":"file-read-failed","analyzedSha":"bb937076de3f7919766c1f25e2e969367cf77e9a","analyzedAt":"2026-09-16T01:37:20.251Z","contentChangedAt":"2026-09-16T01:37:20.251Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}