[ 
https://issues.apache.org/jira/browse/CAMEL-24403?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

mayur mohan updated CAMEL-24403:
--------------------------------
    Priority: Minor  (was: Major)

> camel-mail: MessageRemovedException in processCommit causes null in error log
> -----------------------------------------------------------------------------
>
>                 Key: CAMEL-24403
>                 URL: https://issues.apache.org/jira/browse/CAMEL-24403
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-mail
>            Reporter: mayur mohan
>            Priority: Minor
>
> h2. Problem
> When an IMAP message is expunged (deleted by another client or server-side 
> policy) between the time it is fetched by the MailConsumer and when the 
> on-completion commit callback fires, {code}IMAPMessage.setFlag(){code} throws 
> {code}jakarta.mail.MessageRemovedException{code}. This exception is 
> constructed without a message string so {code}getMessage(){code} returns 
> {code}null{code}, which surfaces in the Camel error log as:
> {noformat}
> Error occurred during committing mail message: 
> com.sun.mail.imap.IMAPMessage@542a494d. 
> Exchange[B5882D23412732A-0000000000000013]. Caused by: 
> [javax.mail.MessageRemovedException - null]
> {noformat}
> The trailing {code}- null{code} is confusing and unhelpful to operators 
> diagnosing the issue.
> h2. Stack Trace
> {noformat}
> javax.mail.MessageRemovedException
>   at com.sun.mail.imap.IMAPMessage.checkExpunged(IMAPMessage.java:280)
>   at com.sun.mail.imap.IMAPMessage.setFlags(IMAPMessage.java:1110)
>   at javax.mail.Message.setFlag(Message.java:596)
>   at 
> org.apache.camel.component.mail.MailConsumer.processCommit(MailConsumer.java:506)
>   at 
> org.apache.camel.component.mail.MailConsumer$1.onComplete(MailConsumer.java:237)
>   at 
> org.apache.camel.support.UnitOfWorkHelper.doneSynchronization(UnitOfWorkHelper.java:104)
>   at 
> org.apache.camel.support.UnitOfWorkHelper.doneSynchronizations(UnitOfWorkHelper.java:89)
>   at 
> org.apache.camel.impl.engine.DefaultUnitOfWork.done(DefaultUnitOfWork.java:238)
>   at 
> org.apache.camel.support.UnitOfWorkHelper.doneUow(UnitOfWorkHelper.java:61)
>   at 
> org.apache.camel.impl.engine.CamelInternalProcessor$UnitOfWorkProcessorAdvice.after(CamelInternalProcessor.java:770)
>   at 
> org.apache.camel.impl.engine.CamelInternalProcessor$UnitOfWorkProcessorAdvice.after(CamelInternalProcessor.java:705)
>   at 
> org.apache.camel.impl.engine.CamelInternalProcessor$AsyncAfterTask.done(CamelInternalProcessor.java:263)
>   at org.apache.camel.AsyncCallback.run(AsyncCallback.java:44)
>   at 
> org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:193)
>   at 
> org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:64)
>   at org.apache.camel.processor.Pipeline.process(Pipeline.java:185)
>   at 
> org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:398)
>   at 
> org.apache.camel.impl.engine.DefaultAsyncProcessorAwaitManager.process(DefaultAsyncProcessorAwaitManager.java:83)
>   at 
> org.apache.camel.support.AsyncProcessorSupport.process(AsyncProcessorSupport.java:41)
>   at 
> org.apache.camel.component.mail.MailConsumer.processExchange(MailConsumer.java:449)
>   at 
> org.apache.camel.component.mail.MailConsumer.processBatch(MailConsumer.java:258)
>   at org.apache.camel.component.mail.MailConsumer.poll(MailConsumer.java:165)
>   at 
> org.apache.camel.support.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:202)
>   at 
> org.apache.camel.support.ScheduledPollConsumer.run(ScheduledPollConsumer.java:116)
>   at 
> org.apache.camel.pollconsumer.quartz.QuartzScheduledPollConsumerJob.execute(QuartzScheduledPollConsumerJob.java:61)
>   at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
>   at 
> org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
> {noformat}
> h2. Root Cause
> {code}MessageRemovedException{code} extends {code}MessagingException{code} 
> but is constructed without a message string, so {code}e.getMessage(){code} 
> returns {code}null{code}. The existing {code}catch (MessagingException 
> e){code} block in {code}processCommit(){code} passes it directly to the 
> exception handler, which includes the null in the formatted log output.
> h2. Fix
> Catch {code}MessageRemovedException{code} before the generic 
> {code}MessagingException{code} handler in {code}processCommit(){code} and 
> wrap it with an explicit description:
> {code:java}
> } catch (MessageRemovedException e) {
>     MessagingException wrapped = new MessagingException(
>             "Message already removed/expunged on server (no flag update 
> possible)", e);
>     getExceptionHandler().handleException(
>             "Error occurred during committing mail message: " + mail, 
> exchange, wrapped);
> } catch (MessagingException e) {
>     getExceptionHandler().handleException(
>             "Error occurred during committing mail message: " + mail, 
> exchange, e);
> }
> {code}
> Expected log output after fix:
> {noformat}
> Caused by: [javax.mail.MessagingException - Message already removed/expunged 
> on server (no flag update possible)]
> {noformat}
> h2. Files Changed
> * 
> {code}components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConsumer.java{code}
> ** Added {code}jakarta.mail.MessageRemovedException{code} import
> ** Added dedicated {code}catch (MessageRemovedException e){code} block before 
> the generic {code}MessagingException{code} handler in 
> {code}processCommit(){code}
> * 
> {code}components/camel-mail/src/test/java/org/apache/camel/component/mail/MailConsumerCommitExpungedMessageTest.java{code}
>  (new file)
> ** {code}testCommitWithExpungedMessageProducesNonNullCause{code}: verifies 
> {code}MessageRemovedException{code} is wrapped in a 
> {code}MessagingException{code} with a non-null message and root cause 
> preserved
> ** {code}testCommitWithOtherMessagingExceptionPassedThroughAsIs{code}: 
> verifies other {code}MessagingException{code} types pass through unchanged
> h2. Pull Request
> https://github.com/apache/camel/pull/25553
> h2. Test Results
> {noformat}
> Tests run: 2, Failures: 0, Errors: 0, Skipped: 0  [JDK 21 / Maven 3.9]
> BUILD SUCCESS
> {noformat}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to