From 04590235145c862e6805bd5f7764ed82ffd6e35e Mon Sep 17 00:00:00 2001 From: Ryan Lue Date: Wed, 6 Nov 2019 16:15:22 +0800 Subject: [PATCH] Fixes issue #2754: Unparseable IMAP responses block email import from inbox Some users experienced an error while fetching emails over IMAP (see GitHub issue below for complete traceback). This error was caused by certain unparseable character sequences in the responses Zammad received from users' configured IMAP servers. The Zammad dev team was not able to reproduce this issue when fetching identical emails from its own servers. Details remain unclear, but we have tracebacks from two distinct occurrences of this issue, and the problematic strings followed the same format: * "\"Jetzt" * "\"RE:" This commit rescues the error in question, records details to the application log, and allows IMAP fetch to proceed to the next message. --- app/models/channel/driver/imap.rb | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/app/models/channel/driver/imap.rb b/app/models/channel/driver/imap.rb index b310d76dd..af67bf76b 100644 --- a/app/models/channel/driver/imap.rb +++ b/app/models/channel/driver/imap.rb @@ -208,6 +208,7 @@ example count_max = 5000 too_large_messages = [] active_check_interval = 20 + result = 'ok' notice = '' message_ids.each do |message_id| count += 1 @@ -222,6 +223,18 @@ example message_meta = nil timeout(FETCH_METADATA_TIMEOUT) do message_meta = @imap.fetch(message_id, ['RFC822.SIZE', 'ENVELOPE', 'FLAGS', 'INTERNALDATE', 'RFC822.HEADER'])[0] + rescue Net::IMAP::ResponseParseError => e + raise if !e.message.match?(/unknown token/) + + result = 'error' + notice += <<~NOTICE + One of your incoming emails could not be imported (#{e.message}). + Please remove it from your inbox directly + to prevent Zammad from trying to import it again. + NOTICE + Rails.logger.error "Net::IMAP failed to parse message #{message_id}: #{e.message} (#{e.class})" + Rails.logger.error '(See https://github.com/zammad/zammad/issues/2754 for more details)' + next end # ignore verify messages @@ -300,7 +313,7 @@ example Rails.logger.info 'done' { - result: 'ok', + result: result, fetched: count_fetched, notice: notice, }