【问题标题】:Ruby: Rescuing the same error type twiceRuby:两次拯救相同的错误类型
【发布时间】:2013-05-17 05:51:41
【问题描述】:

是否可以在 ruby​​ 中多次挽救相同的错误类型?我需要像这样使用 Koala facebook API 库:

begin
  # Try with user provided app token
  fb = Koala::Facebook::API.new(user_access_token)
  fb.put_connections(user_id, {}) # TODO
rescue AuthenticationError
  # User access token has expired or is fake
  fb = Koala::Facebook::API.new(APP_FB_TOKEN)
  fb.put_connections(user_id, {}) # TODO
rescue AuthenticationError
  # User hasn't authed the app on facebook
  puts "Could not authenticate"
  next
rescue => e
  puts "Error when posting to facebook"
  puts e.message
  next
end

如果没有办法两次挽救相同的错误,有没有更好的方法来推理这个问题?

【问题讨论】:

    标签: ruby exception exception-handling


    【解决方案1】:

    您可能应该将其重构为两个单独的方法 - 一个处理异常的“安全”authenticate 方法,以及一个引发异常的“不安全”authenticate! 方法。 authenticate 应该用authenticate! 来定义

    这是一个示例,说明您可以如何做到这一点,并引入了重试实现。

    编辑:重构以使重试独立于 authenticate 方法。

    def authenticate!
      fb = Koala::Facebook::API.new(user_access_token)
      fb.put_connections(user_id.to_s, )
    end
    
    def authenticate
      authenticate!
    rescue => e
      warn "Error when posting to facebook: #{e.message}"
    end
    
    # @param [Integer] num_retries number of times to try code
    def with_retries(num_retries=2)
      yield
    rescue AuthenticationError
      # User hasn't authed the app on facebook
      puts "Could not authenticate"
      # Retry up to twice
      (num_retries-=1) < 1 ? raise : retry
    end
    
    # Authenticate safely, retrying up to 2 times
    with_retries(2) { authenticate }
    
    # Authenticate unsafely, retrying up to 3 times
    with_retries(2) { authenticate! }
    

    【讨论】:

    • 对此我要说的唯一补充,可能是在第二次重试完成后最终引发 AuthenticateError。如果你最终需要提高它。它将允许由其他调用它的代码来处理它,而不仅仅是将其显示到屏幕上。这样错误最终不会丢失。
    • 将重试代码重构为单独的方法可能更有意义,因此您可以安全或不安全地重试。
    • 我进行了重构,以便您可以安全或不安全地重试。
    • 不应该authenticate 调用一个名为with_retries 的私有方法并传入你想要的块吗?我看到你在那里做什么,但它应该是内部实现。
    • 可以,但这种方式让您可以更灵活地选择是否重试。
    【解决方案2】:

    我认为唯一的方法是在rescue 子句中添加一个新的try-rescue 子句:

    begin
      # Try with user provided app token
      fb = Koala::Facebook::API.new(user_access_token)
      fb.put_connections(user_id, {}) # TODO
    rescue AuthenticationError
      begin
        # User access token has expired or is fake
        fb = Koala::Facebook::API.new(APP_FB_TOKEN)
        fb.put_connections(user_id, {}) # TODO
      rescue AuthenticationError
        # User hasn't authed the app on facebook
        puts "Could not authenticate"
        next
      end
    rescue => e
      puts "Error when posting to facebook"
      puts e.message
      next
    end
    

    【讨论】:

      猜你喜欢
      • 2015-06-13
      • 2013-11-27
      • 2017-01-30
      • 2020-12-15
      • 1970-01-01
      • 2013-06-28
      • 2017-06-03
      • 2010-10-07
      • 1970-01-01
      相关资源
      最近更新 更多