Как отловить класс Errno :: ECONNRESET в «случае, когда»? - PullRequest
28 голосов
/ 27 сентября 2010

Мое приложение (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 ]

50 голосов
/ 27 сентября 2010

Это из-за того, что оператор === работает с классом Class

Оператор case внутренне вызывает метод === объекта, с которым вы оцениваете. Если вы хотите проверить класс e, вы просто протестируете против e, а не e.class. Это потому, что e.class попадет в случай when Class, потому что, ну, e.class - это 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

Да, у Руби иногда может быть странная семантика

1 голос
/ 25 октября 2014

Ну, это зависит от того, ссылаетесь ли вы на класс или на константу. Мне, например, пришлось использовать следующую инструкцию 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

Не уверен, что с этим делать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...