Ответ 1
Это хороший вопрос. После исследования немного.
-
Каковы различия между ними в деталях?
Ответ Жозе:
В основном, вы должны использовать
throw
для потока управления и зарезервироватьraise
для ошибок, которые происходят при ошибках разработчиков или при исключительных обстоятельствах.В Эликсире это различие довольно теоретично, но они имеют значение в некоторые языки, такие как Ruby, где используются ошибки/исключения для поток управления дорог, потому что создается объект исключения и backtrace стоит дорого.
- Как выбрать один для использования в конкретном случае использования?
Пожалуйста, проверьте этот ответ Какие ситуации требуют броска в Elixir
Коротко:
raise/rescue
Считайте raise/rescue явно о обработке исключений (некоторые непредвиденные ситуации, такие как ошибки программиста, неправильная среда и т.д.).
throw/catch
Полезен в тех местах, где вы ожидали сбоев. Классическими примерами являются:
- выход из глубоко вложенного рекурсивного вызова:
https://github.com/devinus/poison/blob/master/lib/poison/parser.ex#L34-L46 - нормальная обработка ошибок слишком дорога (может произойти слишком много места): https://github.com/michalmuskala/mongodb_ecto/blob/master/lib/mongo_ecto/objectid.ex#L29-L43
- У вас есть нелокальная конструкция (например, транзакции): https://github.com/elixir-lang/ecto/blob/428126157b1970d10f9d5233397f07c35ce69cac/test/support/test_repo.exs#L84-L98
Последний:
- В чем именно "ситуации, когда невозможно получить значение, если только с помощью throw and catch"?
Скажем, вы пытаетесь запустить какой-то код из процесса, который контролируется Supervisor
, но процесс умирает по непредвиденной причине.
try do
IO.inspect MayRaiseGenServer.maybe_will_raise
rescue
RuntimeError -> IO.puts "there was an error"
end
MayRaiseGenServer
контролируется Supervisor
и по какой-то причине возникает ошибка:
try do
IO.inspect MayRaiseGenServer.maybe_will_raise # <- Code after this line is no longer executed
И тогда вы можете придумать здесь исключение catch:
try do
IO.inspect MayRaiseGenServer.maybe_will_raise
catch
:exit, _ -> IO.puts "there was an error"
end
Ok.Hope, которые достаточно проясняют, что мы ищем.