{"record":{"id":"7a77318f49effcb9","repo":"zed-industries/zed","slug":"measuring-canvas-text-error","errorCode":null,"errorMessage":"measuring Canvas text: {error:?}","messagePattern":"measuring Canvas text: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/gpui_web/src/canvas_text.rs","lineNumber":93,"sourceCode":"            .context(\"Canvas text renderer was called reentrantly\")?;\n        if canvas.is_none() {\n            *canvas = Some(TextCanvas::new()?);\n        }\n        operation(\n            canvas\n                .as_mut()\n                .context(\"Canvas text renderer is unavailable\")?,\n        )\n    })\n}\n\npub(crate) fn measure(text: &str, css_font: &str) -> Result<CanvasTextMetrics> {\n    with_canvas(|canvas| {\n        canvas.configure(css_font)?;\n        let metrics = canvas\n            .context\n            .measure_text(text)\n            .map_err(|error| anyhow!(\"measuring Canvas text: {error:?}\"))?;\n        let metrics = CanvasTextMetrics {\n            advance: metrics.width() as f32,\n            left: -metrics.actual_bounding_box_left() as f32,\n            right: metrics.actual_bounding_box_right() as f32,\n            ascent: metrics.actual_bounding_box_ascent() as f32,\n            descent: metrics.actual_bounding_box_descent() as f32,\n        };\n        ensure!(\n            [\n                metrics.advance,\n                metrics.left,\n                metrics.right,\n                metrics.ascent,\n                metrics.descent\n            ]\n            .into_iter()\n            .all(f32::is_finite),\n            \"Canvas returned non-finite text metrics\"","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/zed-industries/zed/blob/916fc2b8cb3a815cbef4a3b40e13081be72036b6/crates/gpui_web/src/canvas_text.rs#L75-L111","documentation":"Thrown in measure() when canvas.context.measure_text(text) returns a rejected JS promise or throws, after configure(css_font) succeeded. It means the browser refused to compute text metrics for the given text/font on the shared OffscreenCanvas — usually a browser-internal error from the 2D context (empty or invalid font state, oversized string, or a context that has been invalidated), not a problem with the caller's text.","triggerScenarios":"Thrown at crates/gpui_web/src/canvas_text.rs:93 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry the measurement once with a freshly created OffscreenCanvas, as the 2D context may have become invalid","Fall back to approximating metrics from a default font (e.g. cache last-good advance/ascent/descent for the font) so layout can proceed","Log the JsValue error via js_sys::Error::from to surface the browser's message before deciding on retry vs fallback","Sanity-check css_font against known-good values before calling, since a silently ignored bad font leaves the context in a reset ('10px sans-serif') state"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"916fc2b8cb3a815cbef4a3b40e13081be72036b6","analyzedAt":"2026-09-19T19:09:50.599Z","contentChangedAt":"2026-09-19T19:09:50.599Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}