Skip to content

Commit 272fcd0

Browse files
committed
GH-9297: Improve ImapIdleChannelAdapter.callIdle() for cause
Fixes: #9297 For a normal `jakarta.mail.StoreClosedException: * BYE Jakarta Mail Exception: java.net.SocketException: Connection reset` the `ImapIdleChannelAdapter.callIdle()` results in a resubmission (and reconnection) with logging 'Failed to execute IDLE task. Will attempt to resubmit in 10000 milliseconds.'` However, when `selectorExpression` is in used and that one is based on mail `Message` object, we may fail with `FolderClosedException` which is wrapped to the `SpelEvaluationException` and some other stack traces. So, `jakarta.mail.MessagingException` might be deep in the cause chain. * Fix `ImapIdleChannelAdapter` via introducing `getJakartaMailMessagingExceptionFromCause()` utility method which searches for the `jakarta.mail.MessagingException` in cause chain. * Rework `ImapIdleChannelAdapter.callIdle()` logic to rely on this new method **Auto-cherry-pick to `6.3.x` & `6.2.x`**
1 parent 7974f9c commit 272fcd0

File tree

1 file changed

+34
-16
lines changed

1 file changed

+34
-16
lines changed

spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapIdleChannelAdapter.java

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -36,6 +36,7 @@
3636
import org.springframework.integration.transaction.IntegrationResourceHolder;
3737
import org.springframework.integration.transaction.IntegrationResourceHolderSynchronization;
3838
import org.springframework.integration.transaction.TransactionSynchronizationFactory;
39+
import org.springframework.lang.Nullable;
3940
import org.springframework.messaging.MessagingException;
4041
import org.springframework.transaction.support.TransactionSynchronization;
4142
import org.springframework.transaction.support.TransactionSynchronizationManager;
@@ -200,22 +201,24 @@ private void callIdle() {
200201
}
201202
catch (Exception ex) {
202203
publishException(ex);
203-
if (this.shouldReconnectAutomatically
204-
&& ex.getCause() instanceof jakarta.mail.MessagingException messagingException) {
205-
206-
//run again after a delay
207-
logger.info(messagingException,
208-
() -> "Failed to execute IDLE task. Will attempt to resubmit in "
209-
+ this.reconnectDelay + " milliseconds.");
210-
delayNextIdleCall();
211-
}
212-
else {
213-
logger.warn(ex,
214-
"Failed to execute IDLE task. " +
215-
"Won't resubmit since not a 'shouldReconnectAutomatically' " +
216-
"or not a 'jakarta.mail.MessagingException'");
217-
break;
204+
if (this.shouldReconnectAutomatically) {
205+
jakarta.mail.MessagingException messagingException =
206+
getJakartaMailMessagingExceptionFromCause(ex.getCause());
207+
208+
if (messagingException != null) {
209+
//run again after a delay
210+
logger.info(messagingException,
211+
() -> "Failed to execute IDLE task. Will attempt to resubmit in "
212+
+ this.reconnectDelay + " milliseconds.");
213+
delayNextIdleCall();
214+
continue;
215+
}
218216
}
217+
logger.warn(ex,
218+
"Failed to execute IDLE task. " +
219+
"Won't resubmit since not a 'shouldReconnectAutomatically' " +
220+
"or not a 'jakarta.mail.MessagingException'");
221+
break;
219222
}
220223
}
221224
}
@@ -256,6 +259,21 @@ private void delayNextIdleCall() {
256259
}
257260
}
258261

262+
@Nullable
263+
private static jakarta.mail.MessagingException getJakartaMailMessagingExceptionFromCause(Throwable cause) {
264+
if (cause == null) {
265+
return null;
266+
}
267+
if (cause instanceof jakarta.mail.MessagingException messagingException) {
268+
return messagingException;
269+
}
270+
Throwable nextCause = cause.getCause();
271+
if (cause == nextCause) {
272+
return null;
273+
}
274+
return getJakartaMailMessagingExceptionFromCause(nextCause);
275+
}
276+
259277
private class MessageSender implements Consumer<Object> {
260278

261279
MessageSender() {

0 commit comments

Comments
 (0)