¿Cómo capturar la clase Errno :: ECONNRESET en “caso cuando”?

Mi aplicación (Ruby 1.9.2) puede generar diferentes excepciones, incluidas las interrupciones de conexión de red. rescue Exception => e , luego hago case/when manejarlos de diferentes maneras, pero varios errores pasan de mi caso a 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 

Huellas dactilares:

 Errno::ECONNRESET 3 

Esto se debe a cómo el operador === trabaja en la clase Class

La statement del case llama internamente al método === en el objeto que está evaluando. Si desea realizar una prueba para la clase e , solo debe probar contra e , no e.class . Eso es porque e.class caería en el caso de when Class , porque, bueno, e.class es una clase.

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

Sí, Ruby puede tener semánticas extrañas a veces.

Bueno, depende de si usted hace referencia a la clase o la constante. Por ejemplo, he tenido que usar la siguiente statement de caso para que funcione un cierto tipo de detección

 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 

Pero eso es porque estoy trabajando con la clase de excepción real no con la constante. HTTPCLient está elevando un objeto de clase real:

 class TimeoutError < RuntimeError end class ConnectTimeoutError < TimeoutError end 

Aquí hay un hecho sorprendente:

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

No estoy seguro de qué hacer con eso.

    Intereting Posts