GraphiteEditor/Graphite · error

Failed to draw main ring

Error message

Failed to draw main ring

What it means

Draws the main ring of the compass gizmo with ctx.arc(center.x, center.y, MAIN_RING_CENTERLINE_RADIUS, 0., TAU). Like the hover ring above it, the radius is a positive constant, making this .expect defensive: it can only fire on non-finite center coordinates on strict engines or a constant regression. It runs at the end of the compass draw, after the hover ring and arrows.

Source

Thrown at editor/src/messages/portfolio/document/overlays/utility_types_web.rs:777

			let side2 = center + r * DVec2::new(cos * direction.x + sin * direction.y, -sin * direction.x + direction.y * cos);

			self.render_context.begin_path();
			self.render_context.move_to(tip.x, tip.y);
			self.render_context.line_to(side1.x, side1.y);
			self.render_context.line_to(base.x, base.y);
			self.render_context.line_to(side2.x, side2.y);
			self.render_context.close_path();

			self.render_context.set_fill_style_str(color);
			self.render_context.fill();
			self.render_context.set_stroke_style_str(color);
			self.render_context.stroke();
		}

		// Main ring
		self.render_context.set_line_width(MAIN_RING_STROKE_WIDTH);
		self.render_context.begin_path();
		self.render_context.arc(center.x, center.y, MAIN_RING_CENTERLINE_RADIUS, 0., TAU).expect("Failed to draw main ring");
		self.render_context.set_stroke_style_str(COLOR_OVERLAY_BLUE);
		self.render_context.stroke();

		// Restore the old line width
		self.render_context.set_line_width(old_line_width);
	}

	pub fn pivot(&mut self, position: DVec2, angle: f64) {
		let uv = DVec2::from_angle(angle);
		let (x, y) = self.snap_to_physical_pixel_center(position).into();

		self.start_dpi_aware_transform();

		// Circle

		self.render_context.begin_path();
		self.render_context.arc(x, y, PIVOT_DIAMETER / 2., 0., TAU).expect("Failed to draw the circle");
		self.render_context.set_fill_style_str(COLOR_OVERLAY_YELLOW);

View on GitHub (pinned to c507b35645)

Solutions

  1. Apply one finite guard on the center at the top of the compass draw covering hover ring, arrows, and main ring.
  2. Fix NaN at its computation site rather than in the drawing code.
  3. Degrade .expect to a logged .ok().
  4. Assert gizmo constants are positive in debug builds.

Example fix

// before
self.render_context.arc(center.x, center.y, MAIN_RING_CENTERLINE_RADIUS, 0., TAU).expect("Failed to draw main ring");

// after
if center.x.is_finite() && center.y.is_finite() {
	let _ = self.render_context.arc(center.x, center.y, MAIN_RING_CENTERLINE_RADIUS, 0., TAU);
}
Defensive patterns

Strategy: validation

Validate before calling

if !(center.x.is_finite() && center.y.is_finite()) {
	return; // skip the entire compass draw: ring, arrows, and hover ring
}

Type guard

fn is_finite_point(p: DVec2) -> bool {
	p.x.is_finite() && p.y.is_finite()
}

Try / catch

if let Err(err) = self
	.render_context
	.arc(center.x, center.y, MAIN_RING_CENTERLINE_RADIUS, 0., TAU)
{
	log::warn!("failed to draw main ring: {:?}", err);
}

Prevention

When it happens

Trigger: Finishing the compass gizmo draw when the snapped center is NaN from corrupted upstream transform math, or if MAIN_RING_CENTERLINE_RADIUS regresses to a non-positive value.

Common situations: Corrupted viewport/document geometry reaching gizmo rendering; edits to gizmo sizing constants.

Related errors


AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16). Data as JSON: /api/errors/e01f1a471a7d3e39. Report an issue: GitHub.