Skip to content

Fix/enhance sqs partial acknowledgement handling#1562

Merged
tomazfernandes merged 13 commits intoawspring:mainfrom
co2plant:fix/EnhanceSQSPartialAcknowledgementHandling
Mar 8, 2026
Merged

Fix/enhance sqs partial acknowledgement handling#1562
tomazfernandes merged 13 commits intoawspring:mainfrom
co2plant:fix/EnhanceSQSPartialAcknowledgementHandling

Conversation

@co2plant
Copy link
Contributor

@co2plant co2plant commented Jan 25, 2026

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

📜 Description

#1497
I first added logging for partial failures.
I checked the directory and found "SqsTemplate.deleteMessages," so I tried to refactor it to match the style as closely as possible.

💡 Motivation and Context

💚 How did you test it?

In the test code (sqs/listener/acknowledgement/SqsAcknowledgementExecutorTests.java), I changed null to DeleteMessageBatchResponse and added code for partial failures.

{53D7D246-5B6C-4C25-962C-6B3EC52FCF69}

📝 Checklist

  • I reviewed submitted code
  • I added tests to verify changes
  • I updated reference documentation to reflect the change
  • All tests passing
  • No breaking changes

🔮 Next steps

@github-actions github-actions bot added the component: sqs SQS integration related issue label Jan 25, 2026
Copy link
Contributor

@tomazfernandes tomazfernandes left a comment

Choose a reason for hiding this comment

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

Thanks for the PR @co2plant, on a first glance looks good.

Notice that SqsAcknowledgementException has a constructor that accepts separate lists for successfully acknowledged messages and failed acknowledgement messages - it would be useful to populate the lists according to AWS response.

public SqsAcknowledgementException(String errorMessage, Collection<Message<?>> successfullyAcknowledgedMessages,
Collection<Message<?>> failedAcknowledgementMessages, String queue, @Nullable Throwable cause) {
super(errorMessage, cause);
this.queue = queue;
this.failedAcknowledgementMessages = failedAcknowledgementMessages.stream().map(msg -> (Message<?>) msg)
.collect(Collectors.toList());
this.successfullyAcknowledgedMessages = successfullyAcknowledgedMessages.stream().map(msg -> (Message<?>) msg)
.collect(Collectors.toList());
}

Thanks.

DeleteMessageBatch response
- Correlate items using message IDs for accurate mapping
- Pass different lists to the SqsAcknowledgementException constructor to handle partial failures
- Extract partial error handling logic from the deleteMessages method
- Improved code readability and maintainability
- placed the calling method at the top and the helper method at the bottom
@co2plant
Copy link
Contributor Author

Thanks for the review @tomazfernandes!

I was wondering how to separate the failures from the full failures, and your review was very helpful.

I updated the code to map item IDs to message IDs based on the AWS responses and populate the success/failure lists.
I also separated the partial failure handling logic into a separate method to improve readability.

{D81CB6CC-D0D6-420A-B8E1-51F06E4455C1}

@co2plant co2plant marked this pull request as ready for review January 25, 2026 22:47
Copy link
Contributor

@tomazfernandes tomazfernandes left a comment

Choose a reason for hiding this comment

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

Hey @co2plant, looking good.

Left a few suggestions. Also, can you please add a section in the docs explaining how partial Acknowledgement failures are handled?

We could also add to the docs that the resulting SqsAcknowledgementException will be available in AcknowledgementResultCallback, so failed exceptions can be inspected and e.g. retry acknowledging them.

- handle DeleteMessageBatch partial failures in a dedicated method
- map AWS failed entry IDs to original message IDs
- populate SqsAcknowledgementException with successful/failed message lists
- avoid wrapping SqsAcknowledgementException twice
- extend SqsAcknowledgementExecutorTests to assert partial failure mapping
- fix callback interface name to AsyncAcknowledgementResultCallback
- explain that onFailure receives SqsAcknowledgementException on partial failures
- add an example using successful/failed acknowledgement message lists for retry
@github-actions github-actions bot added the type: documentation Documentation or Samples related issue label Feb 18, 2026
@co2plant
Copy link
Contributor Author

Thanks for the review and guidance @tomazfernandes!

I've incorporated your requested changes across the executor, tests, and docs.

Additionally, I introduced a separate fail-safe path: if AWS failure response IDs cannot be correlated with request/message IDs, the batch is treated as a full failure to prevent misclassification, so it can be retried safely by the caller.

I also added tests for this path, and documented in sqs.adoc that failures can be inspected (and retried as needed) via SqsAcknowledgementException in the acknowledgement callback.

{449C04FC-87F9-41C5-9712-5926DABD5777}

@tomazfernandes tomazfernandes merged commit 05daa45 into awspring:main Mar 8, 2026
6 checks passed
@tomazfernandes
Copy link
Contributor

Thanks for the contribution @co2plant, great work! Looking forward to more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: sqs SQS integration related issue type: documentation Documentation or Samples related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants