在Rails中,有没有一种方法可以使“ result_from”短路?

时间:2019-09-17 20:01:12

标签: ruby-on-rails ruby exception redis rescue

我正在尝试为Rails中的Redis进行良好的用户友好型故障安全恢复。我正在使用内置的redis_cache_store并设置了reconnect_attempts,但是如果Redis保持关闭状态,而不是将用户卡在页面上,我想将用户转到自定义错误页面没有响应的页面,不知道发生了什么。

我试图通过重新引发一种新的错误类型failsafe来猴子修补RedisCacheStore中的RedisUnavailableError方法,然后让我的application_controller捕获并redirect_to静置500页。

此问题的出处是,我希望我的应用程序在重定向后才停止。在下面的byebug跟踪中,您可以看到在我包含的倒数第二块之前,已经到达redirect行。

但是它并没有停止;我只包含了一系列被调用的其他方法中的第一个,最终导致了另一次尝试写入Redis的尝试,但仍然失败,然后重新引发了相同的异常序列,Rails不会再捕获第二个异常了。时间(实际上确实如此,那将是一个无限循环)。

所以我的问题是:有什么方法可以使rescue_from块只是 stop 而不会在达到某一行后继续触发其他任何东西?

或者,有什么方法可以动态地“禁用” Redis或在rescue_from块中将缓存存储/设置更改为某个空值,以便任何进一步触发的内容都不会尝试与Redis对话?

    [40, 49] in (DELETED)/redis_failsafe.rb
       40:   rescue ::Redis::BaseConnectionError => e
       41:     byebug
       42:     handle_exception(exception: e, method: method, returning: returning)
       43:     returning
       44:     byebug
    => 45:     raise RedisUnavailableError
       46:     # Re-raise the exception when reconnect attempt fails, so our application controller can handle it.
       47:   end
       48: end
       49: 
    (byebug) c

    [INFO][15:50:51] [3cf7] [GET] [(DELETED):3000] [/suppliers] 
    ∙ Redirecting to 500 page due to: RedisUnavailableError

    [30, 39] in /(DELETED)/application_controller.rb
       30:   authorize_resource class: false
       31: 
       32:   rescue_from RedisUnavailableError do |exception|
       33:     byebug
       34:     Rails.logger.info "Redirecting to 500 page due to: #{exception.message}"
    => 35:     redirect_to '/500.html'
       36:     byebug
       37:   end
       38: 
       39:   rescue_from ActiveRecord::RecordNotFound do
    (byebug) n
    ∙ Redirected to http://(DELETED)/500.html
    Return value is: nil

    [32, 41] in /(DELETED)/application_controller.rb
       32:   rescue_from RedisUnavailableError do |exception|
       33:     byebug
       34:     Rails.logger.info "Redirecting to 500 page due to: #{exception.message}"
       35:     redirect_to '/500.html'
       36:     byebug
    => 37:   end
       38: 
       39:   rescue_from ActiveRecord::RecordNotFound do
       40:     render status: :not_found, plain: 'Not found'
       41:   end
    (byebug) n

    [51, 60] in /(DELETED)/rescuable.rb
       51:   def rescue_with_handler(exception, object: self, visited_exceptions: [])
       52:     visited_exceptions << exception
       53: 
       54:     if handler = handler_for_rescue(exception, object: object)
       55:       handler.call exception
    => 56:       exception
       57:     elsif exception
       58:       if visited_exceptions.include?(exception.cause)
       59:         nil
       60:       else
    (byebug) 

1 个答案:

答案 0 :(得分:0)

  

所以我的问题是:有什么方法可以使result_from块停止并在达到某一行后不继续触发其他任何东西?

是的,只需调用ruby break关键字即可。

break用于完全突破一个障碍。 next用于突破一个块并继续进行下一个迭代(如while循环)。它们非常有用。