31

我的应用程序(Ruby 1.9.2)可能会引发不同的异常,包括网络连接中断。我rescue Exception => e,然后case/when以不同的方式处理它们,但有几个错误直接通过我的案例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

印刷:

Errno::ECONNRESET
3
4

2 回答 2

57

这是因为===操作员在类上的工作方式Class

case语句在内部调用===您正在评估的对象上的方法。如果你想测试e类,你只需测试e,而不是e.class。那是因为e.class会陷入这种when Class情况,因为,e.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

是的,Ruby 有时会有奇怪的语义

于 2010-09-27T06:41:37.753 回答
1

好吧,这取决于您是引用类还是常量。例如,我不得不使用以下案例语句来获得某种类型的检测工作

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

但那是因为我正在使用实际的异常类而不是常量。HTTPCLient 正在引发一个实际的类对象:

class TimeoutError < RuntimeError
end  
class ConnectTimeoutError < TimeoutError
end

这是一个令人费解的事实:

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

不知道该怎么做。

于 2014-10-25T18:25:53.120 回答