flxzt/rnote · error

rendering rsvg document failed, Err

Error message

rendering rsvg document failed, Err: {e:?}

What it means

Thrown by Svg::draw_to_cairo when rsvg's CairoRenderer::render_document fails to render the SVG onto the given cairo context. librsvg parses and renders the document; invalid SVG content or a cairo context in an error state aborts rendering.

Solutions

  1. Validate the SVG string parses (e.g. via usvg::Tree::from_str) before rendering
  2. Check self.bounds is finite and the viewport rectangle is valid
  3. Confirm the target cairo::Context/surface is not already in an error state
  4. Log the wrapped rsvg::Error for the specific parse/render failure

Example fix

// before
renderer.render_document(cx, &rect).map_err(|e| anyhow::anyhow!("rendering rsvg document failed, Err: {e:?}"))?;
// after
if let Err(e) = renderer.render_document(cx, &rect) {
    anyhow::bail!("rendering rsvg document failed: {e:#}; svg_data len={}", self.svg_data.len());
}
Defensive patterns

Strategy: validation

Validate before calling

if self.svg_data.trim().is_empty() { anyhow::bail!("empty svg data"); }
if !self.bounds.extents().iter().all(|v| v.is_finite() && *v > 0.0) { anyhow::bail!("invalid bounds"); }

Type guard

fn valid_bounds(b: &Aabb) -> bool { b.extents().iter().all(|v| v.is_finite() && *v >= 0.0) }

Try / catch

if let Err(e) = renderer.render_document(cx, &rect) {
    log::error!("rsvg render failed: {e:?}");
    return Err(e).context("rendering rsvg document failed");
}

Prevention

When it happens

Trigger: render_document is called with malformed SVG data (bad XML, invalid svg_data after wrap_svg_root), a cairo context that already has an error status, or an invalid viewport rectangle.

Common situations: Exporting a corrupted/stitched-together SVG (merged fragments producing invalid XML), drawing onto a failed surface, or NaN/invalid bounds producing a bad viewport rect.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


AI-assisted analysis of flxzt/rnote@bbc5354502 (2026-09-08). Data as JSON: /api/errors/c5e7c82474d00109. Report an issue: GitHub.

Appendix: source

Thrown at crates/rnote-engine/src/svg.rs:199

            false,
        );
        let stream = gio::MemoryInputStream::from_bytes(&glib::Bytes::from(svg_data.as_bytes()));
        let handle = rsvg::Loader::new()
            .with_unlimited_size(true)
            .read_stream(&stream, None::<&gio::File>, None::<&gio::Cancellable>)
            .context("reading stream to rsvg loader failed.")?;
        let renderer = rsvg::CairoRenderer::new(&handle);
        renderer
            .render_document(
                cx,
                &cairo::Rectangle::new(
                    self.bounds.mins[0],
                    self.bounds.mins[1],
                    self.bounds.extents()[0],
                    self.bounds.extents()[1],
                ),
            )
            .map_err(|e| anyhow::anyhow!("rendering rsvg document failed, Err: {e:?}"))?;
        Ok(())
    }

    /// Generate an image from an Svg.
    ///
    /// Using rsvg for rendering.
    pub fn gen_image(&self, image_scale: f64) -> Result<Image, anyhow::Error> {
        let mut bounds = self.bounds;
        bounds.ensure_positive();
        bounds.assert_valid()?;

        let svg_data = rnote_compose::utils::wrap_svg_root(
            self.svg_data.as_str(),
            Some(bounds),
            Some(bounds),
            false,
        );
        let width_scaled = ((bounds.extents()[0]) * image_scale).round() as u32;

View on GitHub (pinned to bbc5354502)