ruby - standard - ¿Cómo capturar la clase Errno:: ECONNRESET en “caso cuando”?
ruby rescue any error (2)
Bueno, depende de si usted hace referencia a la clase o la constante. Por ejemplo, he tenido que usar la siguiente declaración 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.
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 declaración de 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.