Как отловить класс Errno::ECONNRESET в "случае, когда"?
Мое приложение (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
2 ответа
Это из-за того, как ===
оператор работает на уроке 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
Да, у Руби иногда может быть странная семантика
Ну, это зависит от того, ссылаетесь ли вы на класс или на константу. Мне, например, пришлось использовать следующую инструкцию 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
Но это потому, что я работаю с классом исключений, а не с константой. HTTPCLient вызывает фактический объект класса:
class TimeoutError < RuntimeError
end
class ConnectTimeoutError < TimeoutError
end
Вот загадочный факт:
error = HTTPClient::ConnectTimeoutError.new
HTTPClient::ConnectTimeoutError === error
#=> true
error === HTTPClient::ConnectTimeoutError
#=> false
Не уверен, что с этим делать.