如何在“case when”中捕获Errno :: ECONNRESET类?

我的应用程序(Ruby 1.9.2)可能引发不同的exception,包括网络连接中断。 我rescue Exception => e ,然后做case/when以不同的方式处理它们,但是几个错误直接通过我的案例。

 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 

这是因为===运算符如何在类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有时可能会有奇怪的语义

那么它取决于你是引用类还是常量。 例如,我必须使用以下case语句来使某种类型的检测工作

 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 

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

 class TimeoutError < RuntimeError end class ConnectTimeoutError < TimeoutError end 

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

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

不知道该怎么做。