Skip to content

Expose the fields that caused a rule to fail in the rule evaluation result#8201

Open
kaviska wants to merge 9 commits into
wso2:masterfrom
kaviska:rule-mgt-failed-fields
Open

Expose the fields that caused a rule to fail in the rule evaluation result#8201
kaviska wants to merge 9 commits into
wso2:masterfrom
kaviska:rule-mgt-failed-fields

Conversation

@kaviska

@kaviska kaviska commented Jul 10, 2026

Copy link
Copy Markdown

Proposed changes in this pull request

This PR adds the ability to know which fields caused a rule to fail during evaluation, and exposes them on the RuleEvaluationResult.

Previously, RuleEvaluationResult only reported whether a rule was satisfied (a boolean). Callers had no way to tell why a rule did not match. This PR adds a failedFields list so callers can see the specific field names that failed, which is useful for diagnostics, user feedback, and debugging.

The change is confined to the rule evaluation module and is additive and backward compatible:

  • RuleEvaluationResult — add a failedFields list, a constructor that accepts it, and a getFailedFields() accessor. The existing constructor is kept (it delegates with an empty list), and the accessor returns an unmodifiable, never-null list (empty when the rule is satisfied).
  • RuleEvaluator — while evaluating the OR-of-ANDs rule tree, collect the field names of the failing expressions per OR branch. If a branch passes, the collected failed fields are cleared (the rule is satisfied, so nothing failed); if all branches fail, the failing fields from the branches are retained. Exposed via getFailedFields().
  • RuleEvaluationServiceImpl — pass the evaluator's failed fields into the returned RuleEvaluationResult.

The component provides:

  • The list of fields responsible for a rule not matching, in addition to the existing pass/fail result.
  • Backward compatibility: existing callers that use the boolean result and the old constructor are unaffected. failedFields is an additive side output and does not change the evaluation outcome.

Unit tests assert that the failed fields are reported when a rule fails and are empty when the rule passes.

When should this PR be merged

No preconditions.

Follow up actions

N/A

kaviska and others added 3 commits July 10, 2026 11:53
Track and expose the fields that caused a rule to fail evaluation.

- RuleEvaluationResult: add a failedFields list, a constructor accepting it,
  and a getFailedFields() accessor (empty when the rule is satisfied)
- RuleEvaluator: collect the field names of failing expressions per OR branch,
  clearing them when a branch passes, and expose them via getFailedFields()
- RuleEvaluationServiceImpl: pass the evaluator's failed fields into the result
Assert that getFailedFields() reports the failing field when a rule fails,
and is empty when the rule passes.
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Rule evaluation now captures failed field names, carries them through RuleEvaluationResult, and returns them from the evaluation service. Tests cover failed and successful evaluations.

Changes

Failed field reporting

Layer / File(s) Summary
Track failed fields
components/rule-mgt/.../RuleEvaluator.java
RuleEvaluator records failed fields during AND evaluation, aggregates failures across unsuccessful OR branches, and clears them when a branch succeeds.
Propagate evaluation details
components/rule-mgt/.../RuleEvaluationResult.java, components/rule-mgt/.../RuleEvaluationServiceImpl.java
RuleEvaluationResult adds nullable failed-field storage, a three-argument constructor, and an unmodifiable accessor; the service returns the evaluator’s complete result.
Validate failed field behavior
components/rule-mgt/.../RuleEvaluatorTest.java
Tests verify that failed evaluations return the expected field and successful evaluations return an empty list.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the change, but it omits most required template sections such as Purpose, Goals, Approach, tests, security, and release note. Fill in the template sections, especially Purpose, Goals, Approach, User stories, Release note, Automation tests, Security checks, and Documentation.
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: exposing failed rule fields in the evaluation result.
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 unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.77778% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 53.77%. Comparing base (986db2d) to head (77b9939).
⚠️ Report is 7 commits behind head on master.

Files with missing lines Patch % Lines
...ule/evaluation/api/model/RuleEvaluationResult.java 40.00% 2 Missing and 1 partial ⚠️
...ternal/service/impl/RuleEvaluationServiceImpl.java 80.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##             master    #8201   +/-   ##
=========================================
  Coverage     53.76%   53.77%           
- Complexity    21354    21357    +3     
=========================================
  Files          2199     2199           
  Lines        129636   129648   +12     
  Branches      19366    19367    +1     
=========================================
+ Hits          69704    69712    +8     
- Misses        51437    51439    +2     
- Partials       8495     8497    +2     
Flag Coverage Δ
unit 38.45% <77.77%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Address review feedback on the failed fields feature.

- RuleEvaluator: remove the shared failedFields instance field, which was
  unsafe under concurrent evaluation, and add an evaluate(ruleId, rule, data)
  overload that returns a RuleEvaluationResult carrying the failed fields. The
  boolean evaluate(rule, data) delegates to it.
- RuleEvaluationServiceImpl: use the new evaluate overload and return its result
  directly, so callers read the failed fields from the returned object.
- RuleEvaluationResult: deprecate the two-arg constructor and keep the failed
  fields as-is (null when not set) so callers can distinguish 'not computed'
  from 'no failed fields'.
- Update tests to read the failed fields from the returned result.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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
`@components/rule-mgt/org.wso2.carbon.identity.rule.evaluation/src/main/java/org/wso2/carbon/identity/rule/evaluation/internal/service/impl/RuleEvaluationServiceImpl.java`:
- Line 80: Guard the concatenated debug statement in RuleEvaluationServiceImpl
with if (LOG.isDebugEnabled()) before constructing the message and invoking
result.isRuleSatisfied().
🪄 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: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 4289d3b9-5e00-4da3-af6e-8d4f0d9aeca7

📥 Commits

Reviewing files that changed from the base of the PR and between 279401b and 7e1b00f.

📒 Files selected for processing (4)
  • components/rule-mgt/org.wso2.carbon.identity.rule.evaluation/src/main/java/org/wso2/carbon/identity/rule/evaluation/api/model/RuleEvaluationResult.java
  • components/rule-mgt/org.wso2.carbon.identity.rule.evaluation/src/main/java/org/wso2/carbon/identity/rule/evaluation/internal/service/impl/RuleEvaluationServiceImpl.java
  • components/rule-mgt/org.wso2.carbon.identity.rule.evaluation/src/main/java/org/wso2/carbon/identity/rule/evaluation/internal/service/impl/RuleEvaluator.java
  • components/rule-mgt/org.wso2.carbon.identity.rule.evaluation/src/test/java/org/wso2/carbon/identity/rule/evaluation/core/RuleEvaluatorTest.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/rule-mgt/org.wso2.carbon.identity.rule.evaluation/src/test/java/org/wso2/carbon/identity/rule/evaluation/core/RuleEvaluatorTest.java

kaviska and others added 5 commits July 10, 2026 18:56
Replace the ruleId-overloaded evaluate with a distinctly named
evaluateResult(Rule, Map) method that returns the full result. The rule
id is derived from rule.getId(), so the extra ruleId parameter is no
longer needed. The existing boolean evaluate(Rule, Map) is unchanged and
delegates to evaluateResult, keeping the change purely additive.
RuleEvaluator is an internal class that is excluded from Export-Package,
so it is not reachable outside the bundle and its only caller is
RuleEvaluationServiceImpl. Change the existing evaluate(Rule, Map) to
return RuleEvaluationResult instead of a boolean, and drop the extra
method, leaving a single entry point. Callers that need the boolean use
isRuleSatisfied().
@sonarqubecloud

Copy link
Copy Markdown

@kaviska
kaviska requested a review from Thisara-Welmilla July 15, 2026 03:57
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.

2 participants