fix: distinguish imap auth failures from transient errors with exponential backoff

This commit is contained in:
Tanmay Deep Sharma
2026-02-24 19:52:37 +05:30
parent 2a31ec7afd
commit 2963ccbd47
4 changed files with 19 additions and 7 deletions
@@ -15,6 +15,7 @@ class Inboxes::FetchImapEmailInboxesJob < ApplicationJob
return false if inbox.account.suspended?
return false unless inbox.channel.imap_enabled
return false if inbox.channel.reauthorization_required?
return false if inbox.channel.in_backoff?
return true unless ChatwootApp.chatwoot_cloud?
return false if default_plan?(inbox.account)
+4 -5
View File
@@ -17,11 +17,10 @@ class Inboxes::FetchImapEmailsJob < MutexApplicationJob
key = format(::Redis::Alfred::EMAIL_MESSAGE_MUTEX, inbox_id: channel.inbox.id)
with_lock(key, 5.minutes) { process_email_for_channel(channel, interval) }
channel.clear_imap_backoff!
rescue *ExceptionList::IMAP_EXCEPTIONS => e
Rails.logger.error "Authorization error for email channel - #{channel.inbox.id} : #{e.message}"
channel.apply_imap_backoff!
rescue EOFError, OpenSSL::SSL::SSLError, Net::IMAP::BadResponseError, Net::IMAP::InvalidResponseError,
Net::IMAP::ResponseParseError, Net::IMAP::ResponseReadError, Net::IMAP::ResponseTooLargeError => e
rescue Imap::AuthenticationError => e
Rails.logger.error "Authentication error for email channel - #{channel.inbox.id} : #{e.message}"
channel.authorization_error!
rescue *ExceptionList::IMAP_TRANSIENT_EXCEPTIONS => e
Rails.logger.error "Error for email channel - #{channel.inbox.id} : #{e.message}"
channel.apply_imap_backoff!
rescue LockAcquisitionError
@@ -107,7 +107,11 @@ class Imap::BaseFetchEmailService
def build_imap_client
imap = Net::IMAP.new(channel.imap_address, port: channel.imap_port, ssl: true)
imap.authenticate(authentication_type, channel.imap_login, imap_password)
begin
imap.authenticate(authentication_type, channel.imap_login, imap_password)
rescue Net::IMAP::NoResponseError => e
raise Imap::AuthenticationError, e.message
end
imap.select('INBOX')
imap
end
+9 -1
View File
@@ -1,5 +1,7 @@
require 'net/imap'
class Imap::AuthenticationError < StandardError; end
module ExceptionList
REST_CLIENT_EXCEPTIONS = [RestClient::NotFound, RestClient::GatewayTimeout, RestClient::BadRequest,
RestClient::MethodNotAllowed, RestClient::Forbidden, RestClient::InternalServerError,
@@ -14,6 +16,12 @@ module ExceptionList
IMAP_EXCEPTIONS = [
Errno::ECONNREFUSED, Net::OpenTimeout,
Errno::ECONNRESET, Errno::ENETUNREACH, Net::IMAP::ByeResponseError,
Net::IMAP::NoResponseError, SocketError
SocketError
].freeze
IMAP_TRANSIENT_EXCEPTIONS = (IMAP_EXCEPTIONS + [
EOFError, OpenSSL::SSL::SSLError, Net::IMAP::NoResponseError, Net::IMAP::BadResponseError,
Net::IMAP::InvalidResponseError, Net::IMAP::ResponseParseError,
Net::IMAP::ResponseReadError, Net::IMAP::ResponseTooLargeError
]).freeze
end