Вы сказали, что сами
обернуть спасение в спасение
Исключение Inception
Там нет никакого особого пути, кроме упаковки блоков кода в begin rescue end
блока:
begin
do_something
rescue
begin
Logger.write ...
rescue
...error handling...
end
end
... если вы не используете ActiveSupport: http://api.rubyonrails.org/classes/Kernel.html#method-i-suppress
suppress(Exception) do
# all exceptions will be suppressed
end
..но это не простая вещь, рубин, и я заметил, что вы не добавить рельсы тег на ваш вопрос. Хотя, вы можете реализовать suppress
самостоятельно. Или, просто, вот принять это:
def suppress(*exception_classes)
yield
rescue *exception_classes
end
Используйте, что в вашем спасении:
begin
do_something
rescue
Logger.write ...
suppress Exception do
...error handling...
end
end
В простом старом Руби это должен быть спасает весь путь вниз (и действительно, suppress
является только вложенной спасение), но позвольте мне сказать, что это плохая идея спасти все исключения, по сути, не будучи явным, о том, какое исключение вы спасаете, другими словами, не передавая аргумент класса исключения в rescue
, вы неявно спасаете StandardError
, который является суперклассом для большинства исключений (more info here). Это может привести к затруднению поиска ошибок.
begin
rescue
end
..is так же, как:
begin
rescue StandardError
end
Это гораздо лучше знать, что исключение вы спасая и быть четко об этом:
begin
rescue SomeApiError => e
# do something when this specific exception occurs
end
С этим разобрался вас может использовать каскадную стратегию для спасения ваших исключений:
begin
# do the thing
rescue SomeApiError => e
# specific rescue
rescue SomeOtherError => e
# more broad error handling
rescue
# catch all rescue
end
С учетом вышеизложенного будет выполняться только условие спасения, которое соответствует поднятому исключению, однако код в блоке спасения не будет спасен последующими спасениями, только код в блоке begin
будет спасен.
Если вы хотите иметь блок кода, который всегда работает даже в случае исключения, используйте ключевое слово ensure
:
begin
# code
rescue => e
# rescue code
ensure
# this block will always run exception or not
end
вы можете использовать другой 'начать rescue' блок внутри спасения. Или просто ничего не делайте в спасательном блоке. Я не знаю, в чем проблема. Если код вызывает исключение в блоке 'rescue', я хочу сказать вам: просто исправить ошибку :) – djothefou