Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should I handle AsyncAdapterBlockingExecutionFailedException? #908

Closed
rodrigo-rufino opened this issue Oct 10, 2023 · 9 comments
Closed
Labels
component: sqs SQS integration related issue status: waiting-for-feedback Waiting for feedback from issuer type: question Further information is requested

Comments

@rodrigo-rufino
Copy link

Type: Bug

Component: SQS

Describe the bug

In Spring 2.X, whenever I needed to reprocess a message, I'd throw an error. This caused the message processing to fail, hence, reprocessing it.

In Spring 3.X, the AsyncAdapterBlockingExecutionFailedException is being thrown together with our expected exception.

ERROR [io.awspring.cloud.sqs.sqsListenerEndpointContainer#1-120] [AbstractMessageProcessingPipelineSink] [] Error processing message 18e958e4-6820-4005-8ca0-82b47b6adeed. java.util.concurrent.CompletionException: io.awspring.cloud.sqs.listener.AsyncAdapterBlockingExecutionFailedException: Error executing action in BlockingMessageListenerAdapter
	at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:332)
	at java.base/java.util.concurrent.CompletableFuture.uniApplyNow(CompletableFuture.java:674)
	at java.base/java.util.concurrent.CompletableFuture.uniApplyStage(CompletableFuture.java:662)
	at java.base/java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:2168)
	at io.awspring.cloud.sqs.listener.pipeline.MessageListenerExecutionStage.process(MessageListenerExecutionStage.java:49)
	...

Should I handle this exception? Is it harmless?

@tomazfernandes
Copy link
Contributor

Hey @rodrigo-rufino, this exception is simply a Wrapper that indicates you're using a Blocking (not async) message listener.

The original exception should be down the cause chain.

Please let me know if you have any other questions.

@tomazfernandes tomazfernandes added type: question Further information is requested component: sqs SQS integration related issue status: waiting-for-feedback Waiting for feedback from issuer labels Oct 12, 2023
@rodrigo-rufino
Copy link
Author

@tomazfernandes Is there a way to get the original exception? I'm adding an error handler to my listeners, and they log the entire wrapper exception. It would be nice if I could log only the original one.

Another question: You said I'm using a blocking message listener. Is this a bad practice that I should avoid in my application?

@audiobrian
Copy link

@rodrigo-rufino have you solved this? I'm facing the same situation but only when the input queue has an associated DLQ.

@rodrigo-rufino
Copy link
Author

I just added a ErrorHandler to rethrow de exception: https://docs.awspring.io/spring-cloud-aws/docs/3.0.2/reference/html/index.html#error-handling.

@thomasgerhardt0408
Copy link

thomasgerhardt0408 commented Nov 24, 2023

Hi Developers, we also want to get rid of this ERROR LOG Message "AsyncAdapterBlockingExecutionFailedException". Our implemented SQSReceiver logs the error and rethrow the exception, so that after some retries the messages ends up in the Deadletter queue.
Afterwards we are alerted about this error in cloudwatch. Right now we got two alerts, because of this two different error logs!

Any ideas on how to solve the problem? Why is it not possible to override the framework errorhandling or did I do something wrong? Overwriting with rethrow does not work, we still see the error log.

return SqsMessageListenerContainerFactory.builder()
  .sqsAsyncClient(customSqsAsyncClient)
  .configure(options -> options
       .maxMessagesPerPoll(1)
       .pollTimeout(Duration.ofSeconds(5)))
  .errorHandler(new ErrorHandler<Object>() {
     @Override
     public void handle(Message<Object> message, Throwable t) {
         // ignore AbstractMessageProcessingPipelineSink error
        ReflectionUtils.rethrowRuntimeException(t);
      }
})
.build();

@tomazfernandes
Copy link
Contributor

@tomazfernandes Is there a way to get the original exception? I'm adding an error handler to my listeners, and they log the entire wrapper exception. It would be nice if I could log only the original one.

@rodrigo-rufino, you can add some logic in your error handler to unwrap the exception by traversing the causes and ignoring framework and JDK exceptions such as AsyncAdapterBlockingExecutionFailedException and CompletionException.

We can look into adding some logic to support that in the framework if that's necessary.

@tomazfernandes
Copy link
Contributor

Afterwards we are alerted about this error in cloudwatch. Right now we got two alerts, because of this two different error logs!

@thomasgerhardt0408 we could add an option in AbstractPollingMessageSource to disable the default framework logging. Would you be interested in opening a PR for that?

@audiobrian
Copy link

Hi Developers, we also want to get rid of this ERROR LOG Message "AsyncAdapterBlockingExecutionFailedException". Our implemented SQSReceiver logs the error and rethrow the exception, so that after some retries the messages ends up in the Deadletter queue. Afterwards we are alerted about this error in cloudwatch. Right now we got two alerts, because of this two different error logs!

Any ideas on how to solve the problem? Why is it not possible to override the framework errorhandling or did I do something wrong? Overwriting with rethrow does not work, we still see the error log.

return SqsMessageListenerContainerFactory.builder()
  .sqsAsyncClient(customSqsAsyncClient)
  .configure(options -> options
       .maxMessagesPerPoll(1)
       .pollTimeout(Duration.ofSeconds(5)))
  .errorHandler(new ErrorHandler<Object>() {
     @Override
     public void handle(Message<Object> message, Throwable t) {
         // ignore AbstractMessageProcessingPipelineSink error
        ReflectionUtils.rethrowRuntimeException(t);
      }
})
.build();

Disabling the logger in my logback.xml using the parent package worked for me:
<logger name="io.awspring.cloud.sqs.listener.sink" level="OFF"/>

@tomazfernandes
Copy link
Contributor

tomazfernandes commented Jan 5, 2024

Disabling the logger in my logback.xml using the parent package worked for me:
<logger name="io.awspring.cloud.sqs.listener.sink" level="OFF"/>

Looks like a good enough solution. I'll close the issue due to lack of feedback. We can reopen if necessary.

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 status: waiting-for-feedback Waiting for feedback from issuer type: question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants