{"record":{"id":"3b500b20713295b1","repo":"flxzt/rnote","slug":"finishing-piet-context-failed-err-e","errorCode":null,"errorMessage":"finishing piet context failed, Err: {e:?}","messagePattern":"finishing piet context failed, Err: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/rnote-engine/src/image.rs","lineNumber":385,"sourceCode":"            pixel_width: width_scaled,\n            pixel_height: height_scaled,\n            // cairo renders to bgra8-premultiplied, but we convert it to rgba8-premultiplied\n            memory_format: ImageMemoryFormat::R8g8b8a8Premultiplied,\n        })\n    }\n\n    /// Generates an image with a provided closure that draws onto a [piet_cairo::CairoRenderContext].\n    pub fn gen_with_piet<F>(draw_func: F, bounds: Aabb, image_scale: f64) -> anyhow::Result<Self>\n    where\n        F: FnOnce(&mut piet_cairo::CairoRenderContext) -> anyhow::Result<()>,\n    {\n        let cairo_draw_fn = move |cairo_cx: &cairo::Context| -> anyhow::Result<()> {\n            let mut piet_cx = piet_cairo::CairoRenderContext::new(cairo_cx);\n            // Apply the draw function\n            draw_func(&mut piet_cx)?;\n            piet_cx\n                .finish()\n                .map_err(|e| anyhow::anyhow!(\"finishing piet context failed, Err: {e:?}\"))?;\n            Ok(())\n        };\n\n        Self::gen_with_cairo(cairo_draw_fn, bounds, image_scale)\n    }\n}\n\npub(super) fn convert_image_bgra_to_rgba(_width: u32, _height: u32, mut bytes: Vec<u8>) -> Vec<u8> {\n    for src in bytes.as_chunks_mut::<4>().0 {\n        let (blue, green, red, alpha) = (src[0], src[1], src[2], src[3]);\n        src[0] = red;\n        src[1] = green;\n        src[2] = blue;\n        src[3] = alpha;\n    }\n    bytes\n}\n","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/flxzt/rnote/blob/bbc5354502ba2fc83eec2670b535348825e679a6/crates/rnote-engine/src/image.rs#L367-L403","documentation":"In image generation via cairo, the piet CairoRenderContext's finish() failed after running the caller-supplied draw function. finish() flushes and validates all piet rendering state; an error here means the draw function left the piet context in a bad state or the underlying cairo backend reported an error, so no valid image could be produced.","triggerScenarios":"Calling the public gen_with_piet entry with a draw_func that triggers a cairo error (e.g. invalid path/clip state, unsupported operations) or leaves the piet context unflushed/invalid; cairo surface errors surfacing at finish().","commonSituations":"Rendering a stroke whose geometry produces an invalid cairo path; exporting a bitmap of a document containing strokes that hit cairo backend limits; bugs in custom draw functions passed to gen_with_piet.","solutions":["Inspect the wrapped error `{e:?}` to find which piet/cairo operation failed inside draw_func.","Validate stroke geometry (no NaN/infinite coordinates, sane transform) before drawing.","Ensure the draw function completes all piet operations and does not misuse save/restore or clips.","Update piet-cairo/cairo crates in case of a backend bug."],"exampleFix":"// before\ndraw_func(&mut piet_cx)?;\npiet_cx.finish().map_err(|e| anyhow!(\"finishing piet context failed, Err: {e:?}\"))?;\n// after\ndraw_func(&mut piet_cx).context(\"draw function failed\")?;\npiet_cx.finish().with_context(|| format!(\"finishing piet context failed, Err: {e:?}\"))?;","handlingStrategy":"try-catch","validationCode":"// Rust: ensure bounds and scale are sane before generating the image\nfn gen_params_ok(bounds: kurbo::Rect, scale: f64) -> bool {\n    bounds.is_finite() && bounds.width() > 0.0 && bounds.height() > 0.0 && scale.is_finite() && scale > 0.0\n}","typeGuard":"fn finite_bounds(r: &kurbo::Rect) -> bool {\n    r.x0.is_finite() && r.x1.is_finite() && r.y0.is_finite() && r.y1.is_finite()\n}","tryCatchPattern":"match Image::gen_with_piet(draw_fn, bounds, scale) {\n    Ok(img) => ..., \n    Err(e) => log::error!(\"image generation failed: {e:#}\"),\n}","preventionTips":["Ensure draw functions balance save/restore and produce finite geometry (no NaN/inf).","Validate bounds and scale before invoking generation.","Keep piet/cairo dependencies updated to avoid known backend finish() bugs."],"tags":["rust","rendering","piet","cairo"],"backgroundTag":"image-render-failed","analyzedSha":"bbc5354502ba2fc83eec2670b535348825e679a6","analyzedAt":"2026-09-08T13:20:33.747Z","contentChangedAt":"2026-09-08T13:20:33.747Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}