如何使用rescue
继续循环。我会做一个例子
def self.execute
Foo.some_scope.each do |foo|
# This calls to an external API, and sometimes can raise an error if the account is not active
App::Client::Sync.new(foo).start!
end
end
通常rescue Bar::Web::Api::Error => e
会在方法结束时出现,循环将停止。如果我可以更新已获救的foo
的属性并再次调用该方法,则foo
将不会包含在范围内,我将能够再次启动循环。但问题是,我只希望每个foo
一次。因此,这种方式将再次遍历所有现有的foo
。
我能做到这一点的另一种方式是什么?我可以创建一个在execute
方法顶部调用的私有方法。这可以遍历foo
并更新属性,使它们不属于范围。但这听起来像是一个无限循环。
有没有人有这个好的解决方案?
答案 0 :(得分:2)
您可以在循环中放置begin
和rescue
块。您谈到“更新foo的属性”,但似乎您只希望确保在重新启动循环时不处理此foo
,但您不需要重新启动循环。
def self.execute
Foo.some_scope.each do |foo|
# This calls to an external API, and sometimes can raise an error if the account is not active
begin
App::Client::Sync.new(foo).start!
rescue Bar::Web::Api::Error
foo.update(attribute: :new_value) # if you still need this
end
end
end
答案 1 :(得分:0)
您可以使用retry
。当从begin
块调用时,它将重新执行整个rescue
块。如果您只想重试有限次数,可以使用计数器。类似的东西:
def self.execute
Foo.some_scope.each do |foo|
num_tries = 0
begin
App::Client::Sync.new(foo).start!
rescue
num_tries += 1
retry if num_tries > 1
end
end
end
文档here。