Skip to content

fix(lint): read an action activity's error handling from the action - #1203

Open
tgolembiewski wants to merge 1 commit into
mendixlabs:mainfrom
tgolembiewski:fix/1202-lint-action-error-handling
Open

tgolembiewski wants to merge 1 commit into
mendixlabs:mainfrom
tgolembiewski:fix/1202-lint-action-error-handling

Conversation

@tgolembiewski

Copy link
Copy Markdown
Contributor

Closes #1202

What

CONV013 and CONV014 read an action activity's error handling from the activity-level field, which the reader leaves empty. Mendix stores error handling on the action (Microflows$*Action.ErrorHandlingType), and the reader puts it there. So:

  • CONV013 reported uses '' error handling instead of Custom on every Java/REST/web service call, including handled ones;
  • CONV014 never reported on error continue on an action.

describe was right all along, because getActionErrorHandlingType reads the action (the reflection lookup from #1078).

The fix moves that lookup into sdk/microflows so the describer and the linter share it:

  • ActionActivity.ErrorHandling() returns the action's handling, falling back to the activity field for action types that have none.
  • ActionErrorHandlingType(action) is the existing reflection lookup, moved unchanged from mdl/executor.
  • getActionErrorHandlingType keeps its one exclusion (RestOperationCallAction, CE6035) and then calls ErrorHandling(), so DESCRIBE output does not change.
  • Both lint rules call ErrorHandling(). CONV013's message now names the stored value ('Rollback', 'Continue') instead of ''.

Measured on a blank Mendix 11.12.1 app with mdl-examples/bug-tests/lint-action-error-handling.mdl (four Java calls):

microflow CONV013 before → after CONV014 before → after
MF_Handled (on error { … }) '' → none none → none
MF_HandledNoRollback '' → none none → none
MF_Unhandled (no clause) '' → 'Rollback' none → none
MF_Continue (on error continue) '' → 'Continue' none → CONV014

mx check: 0 errors. describe output for the four microflows is unchanged.

Changes

  • sdk/microflows/error_handling.go: new, ActionActivity.ErrorHandling() and ActionErrorHandlingType().
  • sdk/microflows/error_handling_test.go: new. The lookup test moved here from mdl/executor, plus cases for the action winning, the activity fallback and nil.
  • mdl/linter/rules/conv_error_handling.go: both rules read ErrorHandling().
  • mdl/linter/rules/conv_error_handling_test.go: two new tests with the handling on the action, the way the reader stores it. The existing tests put it on the activity, which is why they passed.
  • mdl/executor/cmd_microflows_show_helpers.go: getActionErrorHandlingType calls the shared accessor, and the local copy of the lookup is removed. Its two test references now use the moved function.
  • mdl-examples/bug-tests/lint-action-error-handling.mdl: the repro.
  • CHANGELOG.md ([Unreleased] / Fixed), and one line in .claude/skills/fix-issue/findings/mdl-other.jsonl.

Tests

  • Each new test fails with its fix reverted:

    • reading the activity field again in the rules fails TestFindUnhandledCalls_HandlingOnTheAction and TestFindContinueErrorHandling_ContinueOnTheAction;
    • making ErrorHandling() return the activity field fails TestActionActivityErrorHandling.
  • The existing tests pass unchanged: the rule tests, and the executor's getActionErrorHandlingType and roundtrip for microflow with error handler does not work - MDL is not complete #1078 round-trip tests.

  • The whole of push-test.yml ran locally on macOS:

    • build and make test;
    • lint-go, check-mdl, check-findings, check-wiki-pages and the tunnel deps;
    • the skill and docs-site MDL blocks;
    • integration tests against mx 11.12.1;
    • govulncheck.

    All green.

CONV013 reported "uses '' error handling instead of Custom" on every Java
action, REST and web service call, including ones with `on error { ... }`,
and CONV014 never reported `on error continue` on an action. Mendix stores
error handling on the action (Microflows$*Action.ErrorHandlingType) and the
reader puts it there; both rules read the activity-level field, which the
reader leaves empty. DESCRIBE was right because getActionErrorHandlingType
reads the action (the reflection lookup from mendixlabs#1078).

Move that lookup into sdk/microflows as ActionActivity.ErrorHandling() and
ActionErrorHandlingType(), and use it in both rules and in the describer, so
the two cannot drift apart again. DESCRIBE output is unchanged.

Measured on a blank 11.12.1 app with four Java calls
(mdl-examples/bug-tests/lint-action-error-handling.mdl): before, CONV013 on
all four with '' and no CONV014; after, CONV013 on the unhandled (Rollback)
and continue calls only, and CONV014 on the continue call.

mendixlabs#1202
@github-actions

Copy link
Copy Markdown

AI Code Review

Critical Issues

None found.

Moderate Issues

None found.

Minor Issues

  • Test file relocation: The test file mdl/executor/microflow_error_handler_roundtrip_test.go was removed entirely, with its tests moved to sdk/microflows/error_handling_test.go. While this is acceptable (the tests are preserved and better organized), it would be helpful to explicitly mention in the PR description that tests were relocated rather than deleted, to avoid confusion during review. However, the new test file does contain equivalent tests plus additional coverage, so functionality is preserved.

What Looks Good

  • Correct root cause fix: The PR correctly identifies that error handling is stored on the action (not the activity) and moves the lookup to a shared location used by both linter and describer.
  • Minimal, focused changes:
    • New shared functions in sdk/microflows/error_handling.go with clear documentation
    • Linter rules updated to use the shared accessor
    • Executor helper simplified to call the shared function
    • Tests moved to appropriate package with additional coverage
  • Thorough testing:
    • New unit tests verify the shared functions work correctly
    • Linter tests confirm both rules now read from action-level storage
    • Existing tests pass (confirming no DESCRIBE behavior change)
    • Full test suite runs successfully
  • Clear evidence:
    • Changelog entry accurately describes the symptom and fix
    • Bug test MDL file demonstrates the issue and solution
    • Measurements show correct behavior before/after
  • Architecture alignment:
    • Eliminates duplication between linter and describer
    • Follows the pattern of putting shared logic in sdk/
    • Maintains backward compatibility (no DESCRIBE changes)
  • Code quality:
    • Well-commented new code explaining why the fix is needed
    • Proper nil handling
    • Uses reflection appropriately (avoids brittle type switches)
    • Follows Go conventions

Recommendation

Approve the PR. The change is correct, minimal, well-tested, and addresses the exact issue described. The minor concern about test file relocation is outweighed by the benefits of better test organization and preservation of all test coverage. No changes are needed before merging.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

This branch has not been deployed

No deployments
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.

Lint CONV013 flags handled Java/REST/web service calls, CONV014 misses "on error continue" on actions

1 participant