GraphiteEditor/Graphite · error
Failed to draw hover ring
Error message
Failed to draw hover ring
What it means
The compass/skew gizmo overlay draws its hover ring with ctx.arc(center.x, center.y, HOVER_RING_CENTERLINE_RADIUS, 0., TAU). The radius is a positive constant, so the negative-radius IndexSizeError route is closed; the .expect can only fire from non-finite center coordinates (compass_center run through snap_to_physical_pixel_center becoming NaN) on engines that reject non-finite doubles, or a regression making the constant non-positive.
Source
Thrown at editor/src/messages/portfolio/document/overlays/utility_types_web.rs:742
const HOVER_RING_STROKE_WIDTH: f64 = HOVER_RING_OUTER_RADIUS - MAIN_RING_INNER_RADIUS;
const HOVER_RING_CENTERLINE_RADIUS: f64 = (HOVER_RING_OUTER_RADIUS + MAIN_RING_INNER_RADIUS) / 2.;
const MAIN_RING_STROKE_WIDTH: f64 = MAIN_RING_OUTER_RADIUS - MAIN_RING_INNER_RADIUS;
const MAIN_RING_CENTERLINE_RADIUS: f64 = (MAIN_RING_OUTER_RADIUS + MAIN_RING_INNER_RADIUS) / 2.;
let Some(show_hover_ring) = show_compass_with_hover_ring else { return };
self.start_dpi_aware_transform();
let center = self.snap_to_physical_pixel_center(compass_center);
// Save the old line width to restore it later
let old_line_width = self.render_context.line_width();
// Hover ring
if show_hover_ring {
self.render_context.set_line_width(HOVER_RING_STROKE_WIDTH);
self.render_context.begin_path();
self.render_context.arc(center.x, center.y, HOVER_RING_CENTERLINE_RADIUS, 0., TAU).expect("Failed to draw hover ring");
self.render_context.set_stroke_style_str(COLOR_OVERLAY_BLUE_50);
self.render_context.stroke();
}
// Arrows
self.render_context.set_line_width(0.01);
for i in 0..4 {
let direction = DVec2::from_angle(i as f64 * FRAC_PI_2 + angle);
let color = if i % 2 == 0 { COLOR_OVERLAY_RED } else { COLOR_OVERLAY_GREEN };
let tip = center + direction * HOVER_RING_OUTER_RADIUS;
let base = center + direction * (MAIN_RING_INNER_RADIUS + MAIN_RING_OUTER_RADIUS) / 2.;
let r = (ARROW_RADIUS.powi(2) + MAIN_RING_INNER_RADIUS.powi(2)).sqrt();
let (cos, sin) = (MAIN_RING_INNER_RADIUS / r, ARROW_RADIUS / r);
let side1 = center + r * DVec2::new(cos * direction.x - sin * direction.y, sin * direction.x + direction.y * cos);
let side2 = center + r * DVec2::new(cos * direction.x + sin * direction.y, -sin * direction.x + direction.y * cos);
View on GitHub (pinned to c507b35645)
Solutions
- Validate the snapped center is finite before drawing the ring.
- Trace NaN to its source in the compass center computation (document bounds, viewport transform).
- Degrade .expect to a logged .ok() so the gizmo fails soft.
- Keep gizmo radius constants positive via a const/debug assertion.
Example fix
// before
self.render_context.arc(center.x, center.y, HOVER_RING_CENTERLINE_RADIUS, 0., TAU).expect("Failed to draw hover ring");
// after
if center.x.is_finite() && center.y.is_finite() {
let _ = self.render_context.arc(center.x, center.y, HOVER_RING_CENTERLINE_RADIUS, 0., TAU);
} Defensive patterns
Strategy: validation
Validate before calling
fn compass_center_drawable(center: DVec2) -> bool {
center.x.is_finite() && center.y.is_finite()
} 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, HOVER_RING_CENTERLINE_RADIUS, 0., TAU)
{
log::warn!("failed to draw hover ring: {:?}", err);
} Prevention
- Validate the snapped compass center once at the top of the gizmo draw
- Const-assert gizmo radius constants stay positive
- Log gizmo inputs on failure to catch upstream NaN quickly
When it happens
Trigger: Rendering the transform compass hover ring when the computed compass center is NaN — typically from degenerate transform or viewport math upstream — or after a regression of the ring-radius constant.
Common situations: Gizmo overlays being the first consumer of corrupted geometry during pointer interaction; refactors turning gizmo constants into computed values.
Related errors
- Failed to draw ellipse
- Failed to draw the circle
- Failed to draw main ring
- Failed to transform circle
- transform should be able to be set to be able to account for
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/1593d3f5495a257c.
Report an issue: GitHub.