Skip to content

WG013: flag catching Throwable or Error in workflow code#75

Open
vikas0686 wants to merge 2 commits into
mainfrom
feature/wg013
Open

WG013: flag catching Throwable or Error in workflow code#75
vikas0686 wants to merge 2 commits into
mainfrom
feature/wg013

Conversation

@vikas0686

@vikas0686 vikas0686 commented Jul 13, 2026

Copy link
Copy Markdown
Owner

New forbidden-catch-type declarative rule type, alongside forbidden-method and mutable-side-effect-equality: flags catch (Throwable ...)/catch (Error ...) reachable from a workflow entry point, including a multi-catch's individual component types. The SDK uses unchecked Error subclasses internally for cancellation and workflow-task-failure control flow; a bare Throwable/Error catch swallows those signals along with everything else, so there's no legitimate reason for workflow code to catch either directly.

A catch clause's caught type is neither a method call nor a constructor call, so no existing CallTarget can match it. CallGraphAnalyzer gains findCaughtTypeMatches, reusing the same path/visiting/context bookkeeping findCallPaths already has (recordMatch, effectiveContext, resolveToSource) without touching search() itself. TemporalRuleSupport.findViolations is refactored to split its filter-and-convert step into a reusable
toViolations(List, ...), so ForbiddenCatchTypeRule shares the same suppressedContexts/requiredContexts handling ForbiddenMethodRule uses instead of a third copy of that logic.

Adds docs/rules/WG013.md and CatchThrowableOrErrorRuleTest, covering direct catch, the Error variant, one-hop-through-a-helper, multi-catch component matching, still-firing inside Workflow.sideEffect() (unlike WG001's suppression), not flagging specific checked exceptions, and not flagging inside Activity implementations.

Summary by CodeRabbit

  • New Features
    • Added WG013 validation to detect workflow code that catches Throwable or Error (including within sideEffect/mutableSideEffect callbacks).
    • Extended declarative rule definitions with a catchTypes parameter to configure which caught types are forbidden.
  • Documentation
    • Added WG013 rule documentation with rationale, examples, and known analysis limitations.
    • Updated the unreleased changelog and shipped the wg013 rule configuration.
  • Tests
    • Added integration coverage for WG013 to verify correct flagging and non-flagging scenarios.

New forbidden-catch-type declarative rule type, alongside forbidden-method
and mutable-side-effect-equality: flags catch (Throwable ...)/catch
(Error ...) reachable from a workflow entry point, including a
multi-catch's individual component types. The SDK uses unchecked Error
subclasses internally for cancellation and workflow-task-failure
control flow; a bare Throwable/Error catch swallows those signals
along with everything else, so there's no legitimate reason for
workflow code to catch either directly.

A catch clause's caught type is neither a method call nor a
constructor call, so no existing CallTarget can match it.
CallGraphAnalyzer gains findCaughtTypeMatches, reusing the same
path/visiting/context bookkeeping findCallPaths already has
(recordMatch, effectiveContext, resolveToSource) without touching
search() itself. TemporalRuleSupport.findViolations is refactored to
split its filter-and-convert step into a reusable
toViolations(List<CallGraphMatch>, ...), so ForbiddenCatchTypeRule
shares the same suppressedContexts/requiredContexts handling
ForbiddenMethodRule uses instead of a third copy of that logic.

Adds docs/rules/WG013.md and CatchThrowableOrErrorRuleTest, covering
direct catch, the Error variant, one-hop-through-a-helper, multi-catch
component matching, still-firing inside Workflow.sideEffect() (unlike
WG001's suppression), not flagging specific checked exceptions, and
not flagging inside Activity implementations.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0706a61d-f3d6-447d-ab0a-8467b9a80b79

📥 Commits

Reviewing files that changed from the base of the PR and between c3e4ff9 and 9a5531f.

📒 Files selected for processing (1)
  • wogu-temporal/src/test/java/dev/wogu/temporal/CatchThrowableOrErrorRuleTest.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • wogu-temporal/src/test/java/dev/wogu/temporal/CatchThrowableOrErrorRuleTest.java

📝 Walkthrough

Walkthrough

Adds declarative WG013 support for detecting workflow-reachable catch (Throwable) and catch (Error) clauses, including call-graph traversal, YAML configuration, violation conversion, tests, documentation, and changelog updates.

Changes

WG013 workflow catch analysis

Layer / File(s) Summary
Rule contract and registration
wogu-temporal/src/main/java/dev/wogu/temporal/RuleDefinition.java, wogu-temporal/src/main/java/dev/wogu/temporal/RuleDefinitionLoader.java, wogu-temporal/src/main/java/dev/wogu/temporal/RuleRegistry.java, wogu-temporal/src/main/resources/rules/wg013.yaml
Adds catchTypes configuration and registers the forbidden-catch-type rule with WG013 metadata.
Catch analysis and violation evaluation
wogu-temporal/src/main/java/dev/wogu/temporal/callgraph/CallGraphAnalyzer.java, wogu-temporal/src/main/java/dev/wogu/temporal/TemporalRuleSupport.java, wogu-temporal/src/main/java/dev/wogu/temporal/ForbiddenCatchTypeRule.java
Traverses reachable workflow code for matching catch types and converts matches into context-filtered violations.
Rule loading and behavior tests
wogu-temporal/src/test/java/dev/wogu/temporal/*Test.java
Tests configuration parsing, registry wiring, validator registration, direct and indirect catches, multi-catch, side effects, and activity exclusions.
WG013 documentation and changelog
docs/rules/WG013.md, CHANGELOG.md
Documents WG013 behavior, examples, recommended fixes, analysis limitations, and the unreleased entry.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant TemporalWorkflowValidator
  participant ForbiddenCatchTypeRule
  participant CallGraphAnalyzer
  participant TemporalRuleSupport
  TemporalWorkflowValidator->>ForbiddenCatchTypeRule: Evaluate workflow classes
  ForbiddenCatchTypeRule->>CallGraphAnalyzer: Find matching caught types
  CallGraphAnalyzer-->>ForbiddenCatchTypeRule: Return reachable matches
  ForbiddenCatchTypeRule->>TemporalRuleSupport: Convert matches to violations
  TemporalRuleSupport-->>TemporalWorkflowValidator: Return filtered violations
Loading

Possibly related issues

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.82% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding WG013 to flag Throwable or Error catches in workflow code.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/wg013

Comment @coderabbitai help to get the list of available commands.

@vikas0686 vikas0686 linked an issue Jul 13, 2026 that may be closed by this pull request

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@wogu-temporal/src/test/java/dev/wogu/temporal/CatchThrowableOrErrorRuleTest.java`:
- Around line 170-200: Update flagsTheThrowableComponentOfAMultiCatch to use the
valid multi-catch alternatives IOException | Error instead of IOException |
Throwable, then change the expected call-path frame from catch (Throwable) to
catch (Error). Preserve the test’s single-violation assertion and surrounding
workflow setup.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 54c5ec26-0d57-496f-80cf-5bf6a86be9a6

📥 Commits

Reviewing files that changed from the base of the PR and between 661734b and c3e4ff9.

📒 Files selected for processing (15)
  • CHANGELOG.md
  • docs/rules/WG013.md
  • wogu-temporal/src/main/java/dev/wogu/temporal/ForbiddenCatchTypeRule.java
  • wogu-temporal/src/main/java/dev/wogu/temporal/RuleDefinition.java
  • wogu-temporal/src/main/java/dev/wogu/temporal/RuleDefinitionLoader.java
  • wogu-temporal/src/main/java/dev/wogu/temporal/RuleRegistry.java
  • wogu-temporal/src/main/java/dev/wogu/temporal/TemporalRuleSupport.java
  • wogu-temporal/src/main/java/dev/wogu/temporal/callgraph/CallGraphAnalyzer.java
  • wogu-temporal/src/main/resources/rules/wg013.yaml
  • wogu-temporal/src/test/java/dev/wogu/temporal/CatchThrowableOrErrorRuleTest.java
  • wogu-temporal/src/test/java/dev/wogu/temporal/MutableSideEffectEqualityRuleTest.java
  • wogu-temporal/src/test/java/dev/wogu/temporal/RuleDefinitionLoaderTest.java
  • wogu-temporal/src/test/java/dev/wogu/temporal/RuleDefinitionTest.java
  • wogu-temporal/src/test/java/dev/wogu/temporal/RuleRegistryTest.java
  • wogu-temporal/src/test/java/dev/wogu/temporal/TemporalWorkflowValidatorTest.java

catch (IOException | Throwable t) would never compile: JLS 14.20
forbids a multi-catch alternative that is a subclass of another
alternative in the same clause, and IOException is a subclass of
Throwable. JavaParser's grammar-level parser doesn't enforce that
semantic rule, so the test still passed mechanically despite exercising
code no real project could contain.

Swapped to IOException | Error (siblings under Throwable, a valid
disjoint multi-catch) and updated the expected call-path frame and
test name to match.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.

WG013 — Catching Throwable or Error in workflow code

1 participant