How to catch Errno::ECONNRESET class in “case when”?

前端 未结 2 1108
醉梦人生
醉梦人生 2020-12-14 01:16

My application (Ruby 1.9.2) may raise different exceptions, including net-connection breaks. I rescue Exception => e, then do case/when to handl

相关标签:
2条回答
  • 2020-12-14 01:23

    Well it depends upon whether you referencing the class or the constant. I have for instance had to use the following case statement to get a certain type of detection working

    def fail(exception_error)
    exception = exception_error
    case exception.class
      when /HTTPClient::ConnectTimeoutError.new/
        status = 'CONNECTION TIMEOUT'
        connection_status = 'DOWN'
      else
        status = 'UNKNOWN FAILURE'
        connection_status = 'DOWN'
    end
    

    But that's because I'm working with the actual Exception Class not the constant. HTTPCLient is raising an actual class object:

    class TimeoutError < RuntimeError
    end  
    class ConnectTimeoutError < TimeoutError
    end
    

    Here's a puzzling fact:

    error = HTTPClient::ConnectTimeoutError.new
    HTTPClient::ConnectTimeoutError === error
    #=> true
    error === HTTPClient::ConnectTimeoutError
    #=> false
    

    Not sure what to make of that.

    0 讨论(0)
  • 2020-12-14 01:37

    This is because of how the === operator works on the class Class

    The case statement internally calls the === method on the object you are evaluating against. If you want to test for e class, you just test against e, not e.class. That's because e.class would fall into the when Class case, because, well, e.class is a Class.

    rescue Exception => e
        case e
            when Errno::ECONNRESET
                p 1
            when Errno::ECONNRESET,Errno::ECONNABORTED,Errno::ETIMEDOUT
                p 2
            else
                p 3
        end
    end
    

    Yeah, Ruby can have weird semantics sometimes

    0 讨论(0)
提交回复
热议问题