Исключение ререйзинга в Ruby с дополнительным строковым аргументом - PullRequest
15 голосов
/ 31 августа 2011

Вот ситуация.Я хочу, чтобы все исключения в doStuff () пузырились в коде, чтобы они обрабатывались на более высоком уровне.

Я также хотел бы записать, как часто любые исключения происходят вdoStuff () также на более высоком уровне, и в настоящее время я делаю это:

begin
  doStuff()
rescue Exception =>
  raise e, "specific error to log in a db"

Код doStuff генерирует десятки исключений, и я хочу захватить каждое из этих событий для помещения в базу данных.Есть doStuff2 (), которая также может выдавать идентичные инструкции, и я хочу знать, из какой функции они вышли.

Добавление дополнительной строки, похоже, меняет само исключение, и я теряю все хорошее форматированиеи проследить информацию, которую имело исходное исключение.

Любые предложения о том, как я могу восстановить исходное исключение, но также отслеживать все исключения, возникающие в doStuff ()?

Ответы [ 3 ]

48 голосов
/ 31 августа 2011

Если вы вызовете raise без передачи аргумента, Ruby повторно вызовет последнее исключение.

begin
  doStuff()
rescue => e
  log_exception(e)
  raise  # This will re-raise the last exception.
end

В качестве примечания я хотел бы дать вам несколько советов о лучших практиках Ruby.

  1. doStuff() метод не соответствует правилам именования Ruby. Вы должны использовать подчеркивание для методов. Пожалуйста, используйте do_stuff. Кроме того, нет необходимости использовать (), если нет аргументов.
  2. Никогда не спасайте Исключение, вместо этого спасите класс самого низкого уровня, который вам нужно спасти. В большинстве случаев вы можете захотеть спасти все виды StandardError или RuntimeError. Фактически, если вы используете функцию спасения, не передавая тип ошибки, Ruby автоматически спасет любой подкласс StandardError. Exception класс очень низкого уровня, он также будет отлавливать синтаксические ошибки и некоторые другие проблемы компилятора. В этом случае вы можете разрешить аварийное завершение приложения, чтобы не развертывать сломанное приложение.
3 голосов
/ 08 июня 2016

Вы можете сохранить обратную трассировку и сообщение первого исключения и создать новое исключение для вызова

begin
rescue Exception => e 
  new_ex = Exception.new("Error while executing ...:#{e.message}")
  new_ex.set_backtrace(e.backtrace)
  raise new_ex
end
2 голосов
/ 23 декабря 2013

Вы не можете вызвать новое исключение и сохранить предыдущее исключение и его трассировку стека из коробки. Вложенные исключения из мира Java, к сожалению, здесь не из коробки. Он будет доступен в Ruby 2.1. Это довольно горячая тема. https://bugs.ruby -lang.org / вопросы / 8257

Вы все еще можете использовать nesty драгоценный камень, чтобы получить его. Все, что вам нужно, это include Nesty::NestedError в ваших классах исключений. Больше информации здесь: https://github.com/skorks/nesty/

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