Skip to content

do not throw when there is no contingency#242

Open
EtienneLt wants to merge 1 commit into
mainfrom
do-not-throw-for-no-contingency
Open

do not throw when there is no contingency#242
EtienneLt wants to merge 1 commit into
mainfrom
do-not-throw-for-no-contingency

Conversation

@EtienneLt
Copy link
Copy Markdown
Contributor

PR Summary

  • do not throw when there is no contingency (needed to clear supervision), it logs a warning and skips the computation.

Signed-off-by: Etienne LESOT <etienne.lesot@rte-france.com>
@EtienneLt EtienneLt self-assigned this May 15, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

The PR updates SecurityAnalysisWorkerService to gracefully handle configurations with no contingencies. Instead of throwing an exception, the service now detects null contingencies in both preRun() and getCompletableFuture(), logs a warning report, and returns early or completes with NO_CALCULATION status. A new message property provides localized text for the warning.

Changes

No-contingency handling in security analysis

Layer / File(s) Summary
No-contingency detection and early return logic
src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java
preRun() now logs a warning and returns early when contingencies are null or when IllegalArgumentException occurs, instead of throwing a business exception. getCompletableFuture() detects all-null contingencies and returns a pre-completed SecurityAnalysisResult with NO_CALCULATION status and empty violation payloads. New private helper logNoContingencies() creates a warning report node using the security.analysis.server.noContingency message template. NO_CALCULATION is added to static imports.
Localized message for no-contingency scenario
src/main/resources/org/gridsuite/securityanalysis/server/reports.properties
Adds the security.analysis.server.noContingency message property for the warning log text.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Title check ✅ Passed The title accurately describes the main change: preventing exception throwing when no contingency is present, which is the core objective of the pull request.
Description check ✅ Passed The description is directly related to the changeset, explaining the rationale for not throwing exceptions when there is no contingency and the desired behavior of logging a warning.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

Review ran into problems

🔥 Problems

Stopped waiting for pipeline failures after 30000ms. One of your pipelines takes longer than our 30000ms fetch window to run, so review may not consider pipeline-failure results for inline comments if any failures occurred after the fetch window. Increase the timeout if you want to wait longer or run a @coderabbit review after the pipeline has finished.


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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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
`@src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java`:
- Around line 110-113: The early-return for all-null contingencies sets the
result status to NO_CALCULATION but downstream saveResult still maps any
non-CONVERGED loadflow status to SecurityAnalysisStatus.DIVERGED, making
NO_CALCULATION indistinguishable; update the code path in the saveResult logic
(or the method that maps LoadFlowResult/status to SecurityAnalysisStatus) to
explicitly check for the NO_CALCULATION sentinel (from
SecurityAnalysisWorkerService/runContext result creation) and map it to a
distinct SecurityAnalysisStatus (e.g., NO_CALCULATION) instead of DIVERGED,
ensuring functions like saveResult, mapLoadflowStatusToSecurityStatus, or
wherever SecurityAnalysisStatus is derived are updated to handle NO_CALCULATION
specially.
- Around line 185-188: The catch for IllegalArgumentException in
SecurityAnalysisWorkerService should not assume every exception means "no
contingency"; add a helper isNoContingencyException(IllegalArgumentException)
that checks the exception message for a contagion of "contingenc"
(case-insensitive), and change the catch to: if isNoContingencyException(e) then
call logNoContingencies(runContext), initialize runContext.contingencies to an
empty list (e.g., Collections.emptyList()) and return; otherwise rethrow or
propagate the exception so real validation/runtime errors aren't swallowed.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 376ef0bc-b82a-4990-8083-9d7ead8ca369

📥 Commits

Reviewing files that changed from the base of the PR and between 27c4d50 and e2af02b.

📒 Files selected for processing (2)
  • src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java
  • src/main/resources/org/gridsuite/securityanalysis/server/reports.properties

Comment on lines +110 to +113
if (runContext.getContingencies().stream().allMatch(contingencyInfos -> contingencyInfos.getContingency() == null)) {
return CompletableFuture.completedFuture(
new SecurityAnalysisResult(new LimitViolationsResult(Collections.emptyList()), NO_CALCULATION, Collections.emptyList()));
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

NO_CALCULATION is introduced but may be persisted as DIVERGED.

With the new early return at Line 110, saveResult still maps any non-CONVERGED load-flow status to SecurityAnalysisStatus.DIVERGED (Line 228 onward). This makes no-contingency runs indistinguishable from real divergence.

💡 Proposed fix
@@
     protected void saveResult(Network network, AbstractResultContext<SecurityAnalysisRunContext> resultContext, SecurityAnalysisResult result) {
+        LoadFlowResult.ComponentResult.Status lfStatus = result.getPreContingencyResult().getStatus();
+        SecurityAnalysisStatus saStatus =
+                lfStatus == LoadFlowResult.ComponentResult.Status.CONVERGED
+                        ? SecurityAnalysisStatus.CONVERGED
+                        : (lfStatus == NO_CALCULATION
+                                ? SecurityAnalysisStatus.NO_CALCULATION
+                                : SecurityAnalysisStatus.DIVERGED);
         resultService.insert(network,
                 resultContext.getResultUuid(),
                 result,
-                result.getPreContingencyResult().getStatus() == LoadFlowResult.ComponentResult.Status.CONVERGED
-                        ? SecurityAnalysisStatus.CONVERGED
-                        : SecurityAnalysisStatus.DIVERGED);
+                saStatus);
     }
🤖 Prompt for 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.

In
`@src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java`
around lines 110 - 113, The early-return for all-null contingencies sets the
result status to NO_CALCULATION but downstream saveResult still maps any
non-CONVERGED loadflow status to SecurityAnalysisStatus.DIVERGED, making
NO_CALCULATION indistinguishable; update the code path in the saveResult logic
(or the method that maps LoadFlowResult/status to SecurityAnalysisStatus) to
explicitly check for the NO_CALCULATION sentinel (from
SecurityAnalysisWorkerService/runContext result creation) and map it to a
distinct SecurityAnalysisStatus (e.g., NO_CALCULATION) instead of DIVERGED,
ensuring functions like saveResult, mapLoadflowStatusToSecurityStatus, or
wherever SecurityAnalysisStatus is derived are updated to handle NO_CALCULATION
specially.

Comment on lines 185 to +188
} catch (IllegalArgumentException e) {
throw new SecurityAnalysisException(SecurityAnalysisBusinessErrorCode.CONTINGENCY_LIST_CONFIG_EMPTY, "The configuration does not contain any contingency.");
// Illegal argument exception seems to be linked to no contingency
logNoContingencies(runContext);
return;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid swallowing all IllegalArgumentException as “no contingency”.

At Line 185, treating every IllegalArgumentException as a no-contingency case can mask real validation/runtime defects. Also, this branch returns without initializing runContext contingencies, which can break downstream logic that streams over them (Line 110).

💡 Proposed fix
 } catch (IllegalArgumentException e) {
-    // Illegal argument exception seems to be linked to no contingency
-    logNoContingencies(runContext);
-    return;
+    if (isNoContingencyException(e)) {
+        runContext.setContingencies(Collections.emptyList());
+        logNoContingencies(runContext);
+        return;
+    }
+    throw e;
 }
private static boolean isNoContingencyException(IllegalArgumentException e) {
    return e.getMessage() != null && e.getMessage().toLowerCase(Locale.ROOT).contains("contingenc");
}
🤖 Prompt for 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.

In
`@src/main/java/org/gridsuite/securityanalysis/server/service/SecurityAnalysisWorkerService.java`
around lines 185 - 188, The catch for IllegalArgumentException in
SecurityAnalysisWorkerService should not assume every exception means "no
contingency"; add a helper isNoContingencyException(IllegalArgumentException)
that checks the exception message for a contagion of "contingenc"
(case-insensitive), and change the catch to: if isNoContingencyException(e) then
call logNoContingencies(runContext), initialize runContext.contingencies to an
empty list (e.g., Collections.emptyList()) and return; otherwise rethrow or
propagate the exception so real validation/runtime errors aren't swallowed.

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.

1 participant