{"record":{"id":"e01f1a471a7d3e39","repo":"GraphiteEditor/Graphite","slug":"failed-to-draw-main-ring","errorCode":null,"errorMessage":"Failed to draw main ring","messagePattern":"Failed to draw main ring","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"editor/src/messages/portfolio/document/overlays/utility_types_web.rs","lineNumber":777,"sourceCode":"\t\t\tlet side2 = center + r * DVec2::new(cos * direction.x + sin * direction.y, -sin * direction.x + direction.y * cos);\n\n\t\t\tself.render_context.begin_path();\n\t\t\tself.render_context.move_to(tip.x, tip.y);\n\t\t\tself.render_context.line_to(side1.x, side1.y);\n\t\t\tself.render_context.line_to(base.x, base.y);\n\t\t\tself.render_context.line_to(side2.x, side2.y);\n\t\t\tself.render_context.close_path();\n\n\t\t\tself.render_context.set_fill_style_str(color);\n\t\t\tself.render_context.fill();\n\t\t\tself.render_context.set_stroke_style_str(color);\n\t\t\tself.render_context.stroke();\n\t\t}\n\n\t\t// Main ring\n\t\tself.render_context.set_line_width(MAIN_RING_STROKE_WIDTH);\n\t\tself.render_context.begin_path();\n\t\tself.render_context.arc(center.x, center.y, MAIN_RING_CENTERLINE_RADIUS, 0., TAU).expect(\"Failed to draw main ring\");\n\t\tself.render_context.set_stroke_style_str(COLOR_OVERLAY_BLUE);\n\t\tself.render_context.stroke();\n\n\t\t// Restore the old line width\n\t\tself.render_context.set_line_width(old_line_width);\n\t}\n\n\tpub fn pivot(&mut self, position: DVec2, angle: f64) {\n\t\tlet uv = DVec2::from_angle(angle);\n\t\tlet (x, y) = self.snap_to_physical_pixel_center(position).into();\n\n\t\tself.start_dpi_aware_transform();\n\n\t\t// Circle\n\n\t\tself.render_context.begin_path();\n\t\tself.render_context.arc(x, y, PIVOT_DIAMETER / 2., 0., TAU).expect(\"Failed to draw the circle\");\n\t\tself.render_context.set_fill_style_str(COLOR_OVERLAY_YELLOW);","sourceCodeStart":759,"sourceCodeEnd":795,"githubUrl":"https://github.com/GraphiteEditor/Graphite/blob/c507b356453361e31638b8bff8f6d46b6da2961e/editor/src/messages/portfolio/document/overlays/utility_types_web.rs#L759-L795","documentation":"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.","triggerScenarios":"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.","commonSituations":"Corrupted viewport/document geometry reaching gizmo rendering; edits to gizmo sizing constants.","solutions":["Apply one finite guard on the center at the top of the compass draw covering hover ring, arrows, and main ring.","Fix NaN at its computation site rather than in the drawing code.","Degrade .expect to a logged .ok().","Assert gizmo constants are positive in debug builds."],"exampleFix":"// before\nself.render_context.arc(center.x, center.y, MAIN_RING_CENTERLINE_RADIUS, 0., TAU).expect(\"Failed to draw main ring\");\n\n// after\nif center.x.is_finite() && center.y.is_finite() {\n\tlet _ = self.render_context.arc(center.x, center.y, MAIN_RING_CENTERLINE_RADIUS, 0., TAU);\n}","handlingStrategy":"validation","validationCode":"if !(center.x.is_finite() && center.y.is_finite()) {\n\treturn; // skip the entire compass draw: ring, arrows, and hover ring\n}","typeGuard":"fn is_finite_point(p: DVec2) -> bool {\n\tp.x.is_finite() && p.y.is_finite()\n}","tryCatchPattern":"if let Err(err) = self\n\t.render_context\n\t.arc(center.x, center.y, MAIN_RING_CENTERLINE_RADIUS, 0., TAU)\n{\n\tlog::warn!(\"failed to draw main ring: {:?}\", err);\n}","preventionTips":["One finite guard per gizmo covering all its arc calls beats per-call expects","Fix NaN at the transform/viewport computation site","Ensure gizmo drawing degrades gracefully so one bad frame does not crash the app"],"tags":["wasm","canvas-2d","overlay","geometry","nan","panic"],"backgroundTag":"canvas-2d-negative-radius","analyzedSha":"c507b356453361e31638b8bff8f6d46b6da2961e","analyzedAt":"2026-08-16T21:57:18.596Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}