Welcome to mirror list, hosted at ThFree Co, Russian Federation.

email_receiver_worker.rb « workers « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 99704b2a71cf11633f875c615a07496c15989de7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# frozen_string_literal: true

class EmailReceiverWorker # rubocop:disable Scalability/IdempotentWorker
  include ApplicationWorker

  data_consistency :always

  sidekiq_options retry: 3

  feature_category :team_planning
  urgency :high
  weight 2

  attr_accessor :raw

  def perform(raw)
    return unless should_perform?

    @raw = raw
    execute_receiver
  end

  def should_perform?
    Gitlab::Email::IncomingEmail.enabled?
  end

  private

  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?

    Gitlab::Email::FailureHandler.handle(receiver, error)
  end
end