diff options
Diffstat (limited to 'app/workers/email_receiver_worker.rb')
-rw-r--r-- | app/workers/email_receiver_worker.rb | 77 |
1 files changed, 69 insertions, 8 deletions
diff --git a/app/workers/email_receiver_worker.rb b/app/workers/email_receiver_worker.rb index 9ceab9bb878..37ed1001c9d 100644 --- a/app/workers/email_receiver_worker.rb +++ b/app/workers/email_receiver_worker.rb @@ -3,25 +3,86 @@ class EmailReceiverWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker + sidekiq_options retry: 3 + feature_category :issue_tracking urgency :high weight 2 + attr_accessor :raw + def perform(raw) - return unless Gitlab::IncomingEmail.enabled? + return unless should_perform? - begin - Gitlab::Email::Receiver.new(raw).execute - rescue => e - handle_failure(raw, e) - end + @raw = raw + execute_receiver + end + + def should_perform? + Gitlab::IncomingEmail.enabled? end private - def handle_failure(raw, error) - Gitlab::AppLogger.warn("Email can not be processed: #{error}\n\n#{raw}") + def execute_receiver + receiver.execute + log_success + rescue StandardError => e + log_error(e) + handle_failure(e) + end + + def receiver + @receiver ||= Gitlab::Email::Receiver.new(raw) + end + + def logger + Sidekiq.logger + end + + def log_success + logger.info(build_message('Successfully processed message', receiver.mail_metadata)) + end + + def log_error(error) + payload = + case error + # Unparsable e-mails don't have metadata we can use + when Gitlab::Email::EmailUnparsableError, Gitlab::Email::EmptyEmailError + {} + else + mail_metadata + end + + # We don't need the backtrace and more details if the e-mail couldn't be processed + if error.is_a?(Gitlab::Email::ProcessingError) + payload['exception.class'] = error.class.name + else + Gitlab::ExceptionLogFormatter.format!(error, payload) + Gitlab::ErrorTracking.track_exception(error) + end + + logger.error(build_message('Error processing message', payload)) + end + + def build_message(message, params = {}) + { + class: self.class.name, + Labkit::Correlation::CorrelationId::LOG_KEY => Labkit::Correlation::CorrelationId.current_id, + message: message + }.merge(params) + end + + def mail_metadata + receiver.mail_metadata + rescue StandardError => e + # We should never get here as long as we check EmailUnparsableError, but + # let's be defensive in case we did something wrong. + Gitlab::ErrorTracking.track_exception(e) + {} + end + def handle_failure(error) return unless raw.present? can_retry = false |