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

佐手、 提交于 2019-12-17 22:38:17

问题


My application (Ruby 1.9.2) may raise different exceptions, including net-connection breaks. I rescue Exception => e, then do case/when to handle them in defferent ways, but several errors go through my cases straight to else.

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

Prints:

Errno::ECONNRESET
3

回答1:


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




回答2:


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.



来源:https://stackoverflow.com/questions/3801469/how-to-catch-errnoeconnreset-class-in-case-when

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!