Ruby错误处理:在子类中挽救异常

时间:2016-09-21 16:12:02

标签: ruby inheritance error-handling custom-error-handling airbrake

我有一组连接到各种API的Adpapter类,而不是。以下是一个简单的一般示例,说明如何设置每个适配器:

class AmazonAdapter
    include Sidekiq::Worker
    def perform(id)
        get_results_from_api(id)
    end
end

class WalmartAdapter
    include Sidekiq::Worker
    def perform(id)
        get_results_from_api(id)
    end
end

因此,通常,通过调用AmazonAdapter.new(500),它将连接到API并返回结果,这取决于您传入的ID作为ID。这是Sidekiq收集过程的一部分,并作为后台作业运行,因此当出现问题时,它不一定会抛出明显的异常或错误来提醒我。

我想使用AirBrake的通知系统在API未正确连接或抛出任何其他错误时通知我,但不停止收集过程或sidekiq。我希望将错误处理和通知系统纳入主流。

我有一些想法是创建一个子类可以继承的ParentClass看起来类似于:

class Adapter
    include Sidekiq::Worker
    def perform(id)
        begin
            #execute subclass perform method
        rescue Exception => e
            Airbrake.notify(e)
        end
    end
end

但我不确定最好的方法来解决这个问题。我真的可以在这个上使用一些建议或帮助,谢谢!

2 个答案:

答案 0 :(得分:0)

Sidekiq中存在一个基本上执行所有操作的瓶颈:Sidekiq::Processor#execute_job,它接收两个参数(worker, cloned_args),然后调用worker.perform(*cloned_args)。因此,为了您的目的,我会先将模块添加到它:

Sidekiq::Processor.prepend(Module.new do
  def execute_job(worker, cloned_args)
    super # CALL ORIGINAL
  rescue => e # NEVER RESCUE FROM EXCEPTION!!!
    Airbrake.notify(e) # NOTIFY
    raise e # RE-RAISE SO SIDEKIQ DOES HIS JOB
  end
end)

在你第一份工作之前打电话给你并且你已经完成了:在Sidekiq的呼叫工作期间发生的所有错误现在都是空运的。

希望它有所帮助。

答案 1 :(得分:0)

我使用类似的构造来提醒我某些chron作业中的失败并ping一个松弛的通道,但好的部分是它不需要继承!一个天真的版本看起来像这样:

class AirbrakeNotifier
  def safe_run
    yield
  rescue StandardError => e
    log_error(e)
    raise e
  end

  private

  def log_error(e)
    # do your logging here
  end
end

然后你的工人会看起来像这样:

class AmazonAdapter
  include Sidekiq::Worker

  def perform(id)
    AirbrakeNotifier.new.safe_run { get_results_from_api(id) }
  end
end

这使您可以更灵活地按照每个类,每个进程以不同的方式配置日志记录,或者实际上您可以想到!