Подтвердить что ты не робот

Поднять пользовательское исключение с помощью аргументов

Я определяю пользовательское исключение на модели в rails как вид обертки. Исключение: (begin[code]rescue[raise custom exception]end)

Когда я поднимаю Exception, я хотел бы передать ему некоторую информацию о a) экземпляре модели, внутренние функции которой вызывают ошибку, и b) ошибка, которая была обнаружена.

Это автоматизированный метод импорта модели, которая заполняется запросом POST от внешнего источника данных.

TL;DR; Как передать аргументы в исключение, учитывая, что вы сами определяете Исключение? У меня есть метод инициализации этого Exception, но синтаксис raise, по-видимому, принимает только класс исключения и сообщение, без дополнительных параметров, которые передаются в процесс создания экземпляра.

4b9b3361

Ответ 1

создайте экземпляр вашего исключения с новым:

class CustomException < StandardError
  def initialize(data)
    @data = data
  end
end
# => nil 
raise CustomException.new(bla: "blupp")
# CustomException: CustomException

Ответ 2

Вот пример кода, добавляющего код к ошибке:

class MyCustomError < StandardError
    attr_reader :code

    def initialize(code)
        @code = code
    end

    def to_s
        "[#{code}] #{super}"
    end
end

И поднять его: raise MyCustomError.new(code), message

Ответ 3

Если вы хотите создать собственный класс ошибок, это скорее всего то, что вы хотите:

class FooError < StandardError
  attr_reader :foo

  def initialize(foo)
   super
   @foo = foo
  end
end

После тестирования всех возможностей, которые я смог найти, это кажется самым чистым, самым минимальным способом - до тех пор, пока вы последовательно передаете свое сообщение в качестве второго аргумента raise.

Обратите внимание, что если вы оставите вызов super,

raise FooError, 'message'

не будет указывать ваше сообщение на экземплярах ошибок (по умолчанию это "FooError", имя класса).

В отличие от комментария @vladCovaliov выше, нет необходимости явно вызывать super с сообщением в качестве аргумента. Явно установка @message выглядит как деталь реализации, которую мы не должны трогать без необходимости.

Интересно, что даже если вы не выполняете вызов super в initialize,

raise FooError.new('bar'), 'message'

все равно правильно установит сообщение. Я не уверен, почему это так.

Если вы хотите установить сообщение об ошибке для исключения (или динамическое сообщение, в зависимости от данных, переданных исключению), определите метод message в своем настраиваемом классе ошибок.

(Протестировано с помощью Ruby 2.1.6.)

Ответ 4

Вы можете создать новый экземпляр вашего подкласса Exception, а затем поднять его. Например:

begin
  # do something
rescue => e
  error = MyException.new(e, 'some info')
  raise error
end