ソース

# frozen_string_literal: true

class RetryTestJob < ActiveJob::Base
  class RetryOnlyDoError < StandardError; end
  class RetryRailseExceptionError < StandardError; end
  class RetryWithoutProcessError < StandardError; end
  class DiscardError < StandardError; end

  FILENAME = "#{Rails.root.to_s}/tmp/jobtest.txt"

  queue_as :high
  discard_on StandardError do |job, e|
    RetryTestJob.write_file("retry_on", job.job_id, job.executions, "#{e.class}: #{e.message}")
  end

  # attempts が0になっても何も行わない
  retry_on RetryWithoutProcessError, wait: 1.seconds, attempts: 3

  # attempts が0になった場合に処理を行う
  retry_on(RetryOnlyDoError, wait: 1.seconds, attempts: 2) do |job, e|
    RetryTestJob.write_file("retry_on", job.job_id, job.executions, "#{e.class}: #{e.message}")
  end

  # 無限にRetryしてしまう
  retry_on(RetryRailseExceptionError, wait: 1.seconds, attempts: 2) do |job, e|
    RetryTestJob.write_file("retry_on", job.job_id, job.executions, "#{e.class}: #{e.message}")
    raise StandardError, "raise StandardError from retry_on: #{job.executions}, #{e.message}"
  end

  def perform
    RetryTestJob.write_file("perform", job_id, executions)

    # 確認したいエラーに切り替える
    # error = StandardError
    error = RetryOnlyDoError
    # error = RetryRailseExceptionError
    # error = RetryWithoutProcessError

    raise error, "raise #{error.name} from perform: #{job_id}, #{executions}"
  end

  private

  def self.write_file(action, job_id, executions, message=nil)
    File.open(FILENAME, 'a') { |f| f.write("#{action}[#{job_id}, #{executions}]#{message ? ": #{message}" : ""}\n") }
  end
end

結果

StandardError の場合

perform[fdf6cc91-2f25-4c9c-ac7c-aedbe2202bea, 1]
retry_on[fdf6cc91-2f25-4c9c-ac7c-aedbe2202bea, 1]: StandardError: raise StandardError from perform: fdf6cc91-2f25-4c9c-ac7c-aedbe2202bea, 1

RetryOnlyDoError の場合

perform[304646d3-649d-422c-9b04-0b0f551f49c7, 1]
perform[304646d3-649d-422c-9b04-0b0f551f49c7, 2]
retry_on[304646d3-649d-422c-9b04-0b0f551f49c7, 2]: RetryTestJob::RetryOnlyDoError: raise RetryTestJob::RetryOnlyDoError from perform: 304646d3-649d-422c-9b04-0b0f551f49c7, 2

RetryRailseExceptionError の場合

retry_on 内でエラーが発生した場合は、無限に実行されるので気をつける。

perform[bff00afd-a3a1-4bf4-93ed-987ed600bed8, 1]
perform[bff00afd-a3a1-4bf4-93ed-987ed600bed8, 2]
retry_on[bff00afd-a3a1-4bf4-93ed-987ed600bed8, 2]: RetryTestJob::RetryRailseExceptionError: raise RetryTestJob::RetryRailseExceptionError from perform: bff00afd-a3a1-4bf4-93ed-987ed600bed8, 2
perform[bff00afd-a3a1-4bf4-93ed-987ed600bed8, 2]
retry_on[bff00afd-a3a1-4bf4-93ed-987ed600bed8, 2]: RetryTestJob::RetryRailseExceptionError: raise RetryTestJob::RetryRailseExceptionError from perform: bff00afd-a3a1-4bf4-93ed-987ed600bed8, 2
perform[bff00afd-a3a1-4bf4-93ed-987ed600bed8, 2]
retry_on[bff00afd-a3a1-4bf4-93ed-987ed600bed8, 2]: RetryTestJob::RetryRailseExceptionError: raise RetryTestJob::RetryRailseExceptionError from perform: bff00afd-a3a1-4bf4-93ed-987ed600bed8, 2

RetryWithoutProcessError

perform[aae6bf69-422d-44b2-b575-e7d425f0e976, 1]
perform[aae6bf69-422d-44b2-b575-e7d425f0e976, 2]
perform[aae6bf69-422d-44b2-b575-e7d425f0e976, 3]