From c8d824d3471ccc417f4d95e1ba9ab509906f5687 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Sat, 28 Mar 2026 09:18:26 +0100 Subject: [PATCH] fix: only skip DO_TRY edges to internal children, keep continuation edges MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous fix skipped ALL edges from DO_TRY nodes, which also removed the continuation edge to the next node in the main flow (causing LOG nodes to appear disconnected). Now checks if the target is a descendant of the DO_TRY ELK node — only internal edges are skipped, continuation edges to the next main flow node are kept. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../app/diagram/ElkDiagramRenderer.java | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/diagram/ElkDiagramRenderer.java b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/diagram/ElkDiagramRenderer.java index c8ca65e4..4c6bd085 100644 --- a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/diagram/ElkDiagramRenderer.java +++ b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/diagram/ElkDiagramRenderer.java @@ -295,19 +295,20 @@ public class ElkDiagramRenderer implements DiagramRenderer { // Create ELK edges — skip edges that cross between different ELK root graphs if (graph.getEdges() != null) { for (RouteEdge re : graph.getEdges()) { - // Skip all edges originating from DO_TRY nodes — these are entry/handler - // edges that don't need layout (try body has its own internal flow, - // handler edges are like route-level ON_EXCEPTION edges) - if (doTryNodeIds.contains(re.getSource())) { - continue; - } - ElkNode sourceElk = elkNodeMap.get(re.getSource()); ElkNode targetElk = elkNodeMap.get(re.getTarget()); if (sourceElk == null || targetElk == null) { continue; } + // Skip edges from DO_TRY to its own children (entry + handler edges). + // Keep edges from DO_TRY to nodes OUTSIDE it (continuation edges). + if (doTryNodeIds.contains(re.getSource())) { + if (isDescendantOf(targetElk, sourceElk)) { + continue; + } + } + // Skip edges that cross ELK root boundaries ElkNode sourceRoot = getElkRoot(sourceElk); ElkNode targetRoot = getElkRoot(targetElk); @@ -717,6 +718,16 @@ public class ElkDiagramRenderer implements DiagramRenderer { // ---------------------------------------------------------------- /** Walk up to the top-level root of an ELK node's hierarchy. */ + /** Check if 'child' is a descendant of 'ancestor' in the ELK node hierarchy. */ + private boolean isDescendantOf(ElkNode child, ElkNode ancestor) { + ElkNode current = child.getParent(); + while (current != null) { + if (current == ancestor) return true; + current = current.getParent(); + } + return false; + } + private ElkNode getElkRoot(ElkNode node) { ElkNode current = node; while (current.getParent() != null) {