Skip to content

fix(ConsumerService): ensure study creation error notification is always emitted on case import failure#1027

Open
freddidierRTE wants to merge 1 commit into
mainfrom
flakyTest
Open

fix(ConsumerService): ensure study creation error notification is always emitted on case import failure#1027
freddidierRTE wants to merge 1 commit into
mainfrom
flakyTest

Conversation

@freddidierRTE

@freddidierRTE freddidierRTE commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Isolate deleteStudyIfNotCreationInProgress in its own try/catch in
consumeCaseImportFailed so that emitStudyCreationError is always called
even if the deletion fails due to a concurrent transaction that already
cleaned up the StudyCreationRequestEntity.

This was causing a flaky test (testCreateStudyWithErrorDuringCaseImport)
when running the full test suite because the WireMock stub stubImportNetworkWithServerError
simulates a situation that does not exist in production:

it returns a 5xx HTTP response AND sends a DLX message simultaneously.

In reality, a synchronous 5xx means the network conversion server
never processed the request and therefore never publishes on case.import.start,
so no DLX message would ever be generated.

This artificial combination caused the catch block in
createStudy and the DLX consumer to race against each other trying to
delete the same StudyCreationRequestEntity. Depending on thread
scheduling, the consumer's delete could throw an
ObjectOptimisticLockingFailureException, which was silently caught at the
outer level, preventing emitStudyCreationError from being called and
leaving the test waiting for a message that never arrived.

Solution was just to catch an exception but as sonar complains with nested try/catch and complexity the method has been cut in two

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The study creation failure handler now catches exceptions from study deletion and logs a warning instead of propagating the deletion failure.

Changes

Study failure handling

Layer / File(s) Summary
Study deletion exception handling
src/main/java/org/gridsuite/study/server/service/ConsumerService.java
The STUDY_CREATION failure branch wraps study deletion in try/catch and logs a warning when deletion fails.

Suggested reviewers: etiennehomer

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Title check ✅ Passed The title accurately summarizes the main change: keeping study creation error notification emission working on case import failure.
Description check ✅ Passed The description is clearly related to the code change and explains the retry/try-catch fix and flaky test context.

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.

@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.

🧹 Nitpick comments (1)
src/main/java/org/gridsuite/study/server/service/ConsumerService.java (1)

358-362: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Preserve the deletion exception in the warning log.

Logging only e.getMessage() discards the exception type and stack trace, making intermittent ObjectOptimisticLockingFailureException failures difficult to diagnose.

Proposed fix
                         } catch (Exception e) {
-                            LOGGER.warn("Could not delete study during case import failure handling: {}", e.getMessage());
+                            LOGGER.warn("Could not delete study '{}' during case import failure handling", studyUuid, e);
                         }
🤖 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/study/server/service/ConsumerService.java` around
lines 358 - 362, Update the catch block around
studyService.deleteStudyIfNotCreationInProgress in ConsumerService to pass the
caught exception to LOGGER.warn, preserving its type and stack trace while
retaining the existing contextual warning message.
🤖 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.

Nitpick comments:
In `@src/main/java/org/gridsuite/study/server/service/ConsumerService.java`:
- Around line 358-362: Update the catch block around
studyService.deleteStudyIfNotCreationInProgress in ConsumerService to pass the
caught exception to LOGGER.warn, preserving its type and stack trace while
retaining the existing contextual warning message.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e249ff96-c619-4408-a300-f3f9159bc1bc

📥 Commits

Reviewing files that changed from the base of the PR and between 6c55c2c and 864c415.

📒 Files selected for processing (1)
  • src/main/java/org/gridsuite/study/server/service/ConsumerService.java

…ays emitted on case import failure

Isolate deleteStudyIfNotCreationInProgress in its own try/catch in
consumeCaseImportFailed so that emitStudyCreationError is always called
even if the deletion fails due to a concurrent transaction that already
cleaned up the StudyCreationRequestEntity.

This was causing a flaky test (testCreateStudyWithErrorDuringCaseImport)
when running the full test suite because the WireMock stub stubImportNetworkWithServerError
simulates a situation that does not exist in production:

it returns a 5xx HTTP response AND sends a DLX message simultaneously.

In reality, a synchronous 5xx means the network conversion server
never processed the request and therefore never publishes on case.import.start,
so no DLX message would ever be generated.

This artificial combination caused the catch block in
createStudy and the DLX consumer to race against each other trying to
delete the same StudyCreationRequestEntity. Depending on thread
scheduling, the consumer's delete could throw an
ObjectOptimisticLockingFailureException, which was silently caught at the
outer level, preventing emitStudyCreationError from being called and
leaving the test waiting for a message that never arrived.

Signed-off-by: freddidierRTE <[email protected]>
@sonarqubecloud

Copy link
Copy Markdown

if (receiver.getCaseImportAction() == CaseImportAction.STUDY_CREATION) {
try {
studyService.deleteStudyIfNotCreationInProgress(studyUuid, userId);
} catch (Exception e) {

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.

maybe catch ObjectOptimisticLockingFailureException instead and add comment that if there are races to delete the study we swaller the exception ?

try {
studyService.deleteStudyIfNotCreationInProgress(studyUuid, userId);
} catch (Exception e) {
LOGGER.warn("Could not delete study during case import failure handling: {}", e.getMessage());

@jonenst jonenst Jul 24, 2026

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.

maybe add the same handling or at least a comment on the other places in the code participating in this race ? If I understand correctly, StudyService::createStudy try catch ? To me even if it's not happening right now, we could some day be in a situation where the call to network-conversion-server to return 500 even though it published a message (maybe proxies, maybe the code has changed and it throws after publishing the message, maybe something else)

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