Skip to content

fix: rejoin empty error handlers inside branch bodies#496

Merged
ako merged 1 commit intomendixlabs:mainfrom
hjotha:submit/branch-empty-error-handler-rejoin
May 2, 2026
Merged

fix: rejoin empty error handlers inside branch bodies#496
ako merged 1 commit intomendixlabs:mainfrom
hjotha:submit/branch-empty-error-handler-rejoin

Conversation

@hjotha
Copy link
Copy Markdown
Contributor

@hjotha hjotha commented May 2, 2026

Closes #495.

Summary

  • routes pending empty no-output custom error handlers when IF branch bodies connect one statement to the next
  • applies the same fix to enum-split branch bodies
  • keeps output-dependent custom handlers on the existing skip-var path
  • adds a synthetic IF-branch regression test

Validation

  • go test ./mdl/executor -run 'EmptyNoOutputHandler.*Branch|EmptyNoOutputHandlerRejoins|OutputHandlerInReturningBranch' -v
  • make build
  • make lint-go
  • make test

Symptom: an empty custom error handler inside a structured branch could round-trip as an explicit `return;` handler even though the authored handler should continue to the next branch action.

Root cause: the top-level flow builder routes pending empty error handlers when connecting one statement to the next, but IF and enum-split branch builders connected sequential branch statements directly and skipped that pending handler rejoin step.

Fix: when branch builders connect a statement that owns an empty no-output custom handler to the next branch statement, run the same pending error-handler routing used by the top-level graph builder. Output-dependent handlers are left to the existing skip-var path so they still avoid unsafe success tails.

Tests: added a synthetic IF-branch regression test; `go test ./mdl/executor -run 'EmptyNoOutputHandler.*Branch|EmptyNoOutputHandlerRejoins|OutputHandlerInReturningBranch' -v`; `make build`; `make lint-go`; `make test`.
@ako
Copy link
Copy Markdown
Collaborator

ako commented May 2, 2026

Review: fix: rejoin empty error handlers inside branch bodies

Verdict: Approve with minor note

What the PR does

Fixes issue #495: when a CALL MICROFLOW with an empty no-output custom error handler appears inside an IF branch body (then or else) or an enum-split branch body, the pending error handler flow wasn't wired to the next statement in that branch. The fix adds the same rejoin call that the top-level flow loop already performs.

No blockers

Minor: outer guard is redundant, creates inconsistency with the top-level pattern

The three new blocks read:

if fb.emptyErrorHandlerFrom == lastThenID {
    fb.addPendingErrorHandlerFlowForStatement(...)
}

But addPendingErrorHandlerFlowForStatementaddPendingErrorHandlerFlowForState already has this guard internally:

if state.emptyFrom != "" {
    if state.emptyFrom != originID {
        return state  // no-op
    }

Calling it when there's no pending handler, or when the handler is from a different origin, is already a safe no-op. The top-level loop in cmd_microflows_builder_graph.go:98 calls addPendingErrorHandlerFlowForStatement unconditionally — no guard. The branch-body version's outer if is functionally correct but redundant, and creates a subtle inconsistency that makes readers wonder why the two call sites look different.

Could drop the outer check to mirror the top-level pattern. Not a blocker — the code is correct either way.

Positive notes

  • Clean, focused fix — 3 lines of logic added in each of 3 places, matching the existing top-level pattern
  • br.body[j+1:] and s.ThenBody[i+1:] are safe when j/i is the last index (empty slice is valid in Go)
  • New test directly reproduces the failure: IF-branch with no-output handler followed by a continuation activity, asserts the error path reaches the continuation
  • No bundled unrelated changes

@ako ako merged commit 5fa4827 into mendixlabs:main May 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Empty custom error handlers inside branch bodies can round-trip as return

3 participants