0

I'm trying to do something that seems to me quite basic but I can't figure out a way to get it DRY.

This is the code I had initially:

my first worker

class WorkerOne < BaseWorker
  def perform
    # do stuff
  rescue *exceptions_to_rescue_with_error => error
    job_error(error, try_later: false)
  rescue *exceptions_to_rescue_with_error_and_try_later => error
    job_error(error, try_later: true)
  rescue *exceptions_to_rescue_with_warning => message
    job_warning(message, try_later: false)
  end
end

my second worker

class WorkerTwo < BaseWorker
  def perform
    # do stuff
  rescue *exceptions_to_rescue_with_error => error
    job_error(error, try_later: false)
  rescue *exceptions_to_rescue_with_error_and_try_later => error
    job_error(error, try_later: true)
  rescue *exceptions_to_rescue_with_warning => message
    job_warning(message, try_later: false)
  end
end

the parent class

class BaseWorker
  def exceptions_to_rescue_with_error
    [
      Exceptions::SomeOtherError,
      ActiveRecord::RecordNotFound
    ]
  end

  def exceptions_to_rescue_with_error_and_try_later
    [
      Exceptions::SomeError1,
      Exceptions::SomeError2,
    ]
  end

  def exceptions_to_rescue_with_warning
    [
      Exceptions::SomeWarning
    ]
  end
end

This is the method I'm adding to BaseWorker to make it work:


  def self.with_job_rescue_for_perfom
    define_method(:perform) do |*args, &block|
      self.perform(*args, &block)
      rescue *exceptions_to_rescue_with_error => error
        job_error(error, try_later: false)
      rescue *exceptions_to_rescue_with_error_to_try_later => error
        job_error(error, try_later: true)
      rescue *exceptions_to_rescue_with_warning => message
        job_warning(message, try_later: false)
    end
  end
end

I'm stuck there and I don't see where I should look into next. It seems the method used here does not work for me as I'm not using a module.

Any idea?

Daniel Costa
  • 275
  • 2
  • 14

1 Answers1

0

I would do something like that :

class BaseWorker
  def exceptions_to_rescue_with_error
    [
      Exceptions::SomeOtherError,
      ActiveRecord::RecordNotFound
    ]
  end

  def exceptions_to_rescue_with_error_and_try_later
    [
      Exceptions::SomeError1,
      Exceptions::SomeError2,
    ]
  end

  def exceptions_to_rescue_with_warning
    [
      Exceptions::SomeWarning
    ]
  end

  def perform
    do_stuff
  rescue *exceptions_to_rescue_with_error => error
    job_error(error, try_later: false)
  rescue *exceptions_to_rescue_with_error_and_try_later => error
    job_error(error, try_later: true)
  rescue *exceptions_to_rescue_with_warning => message
    job_warning(message, try_later: false)
  end
end

class WorkerOne < BaseWorker
  def do_stuff
    # do stuff
  end
end

class WorkerTwo < BaseWorker
  def do_stuff
    # do stuff
  end
end
Thomas
  • 1,613
  • 8
  • 8
  • What I'm trying to do here, would be to redefine `perform` and keep both names the same. – Daniel Costa Mar 09 '19 at 13:55
  • If these exceptions are of your own construction consider addding a method to them so you can do things like `if exception.can_retry?` or `if exception.warning?` to break out the behaviour in a more general way. – tadman Mar 09 '19 at 18:50