Elixir - try/catch vs try/rescue?
elixir
Solution
It's a good question.After research a bit.
What is the differences between them in details?
José's answer:
Mainly, you should use `throw` for control-flow and reserve `raise` for errors, which happens on developer mistakes or under exceptional circumstances.
In Elixir, this distinction is rather theoretical, but they matter in some languages like Ruby, where using errors/exceptions for control-flow is expensive because creating the exception object and backtrace is expensive.
- How should I pick one to use in a specific use case?
Please check this answer Which situations require throw catch in Elixir
Shortly:
`raise/rescue`
Consider raise/rescue to be explicitly about exception handling (some unexpected situation like programmer errors, wrong environment, etc).
`throw/catch`
Is useful in places where you have expected failures. Classic examples are:
- exiting a deeply nested recursive call: https://github.com/devinus/poison/blob/master/lib/poison/parser.ex#L34-L46
- normal error handling is too expensive (can occur in too many places): https://github.com/michalmuskala/mongodb_ecto/blob/master/lib/mongo_ecto/objectid.ex#L29-L43
- you have an non-local construct (like transactions): https://github.com/elixir-lang/ecto/blob/428126157b1970d10f9d5233397f07c35ce69cac/test/support/test_repo.exs#L84-L98
The last one:
- What exactly are 'the situations where it is not possible to retrieve a value unless by using throw and catch'?
Let's say you are trying to running some code from a process that is supervised by a `Supervisor` but the process dies for an unexpected reason.
try do
IO.inspect MayRaiseGenServer.maybe_will_raise
rescue
RuntimeError -> IO.puts "there was an error"
end
`MayRaiseGenServer` is supervised by a `Supervisor` and for some reason an error was raised:
try do
IO.inspect MayRaiseGenServer.maybe_will_raise # <- Code after this line is no longer executed
And then you can come up with using catch an exception here:
try do
IO.inspect MayRaiseGenServer.maybe_will_raise
catch
:exit, _ -> IO.puts "there was an error"
end
Ok.Hope that clarify enough what we are looking for.
Problem
Background Both `try/rescue` and `try/catch` are error handling techniques in Elixir. According the corresponding chapter in the introduction guide. Errors can be rescued using the `try/rescue` construct On the other hand, `throw` and `catch` are reserved for situations where it is not possible to retrieve a value unless by using `throw` and `catch`. Doubts I have a brief understanding that `rescue` is for errors. While `catch` is for any value. However, - When should I make use of the error handling mechanisms in Elixir? - What are the differences between them in detail? - How should I pick one to use in a specific use case? - What exactly are 'the situations where it is not possible to retrieve a value unless by using `throw` and `catch`'?