pm100
Difference between try / rescue and try / throw
Whats the difference between the two? They seem to do identical things but one is doced as ‘only use very rarely’
First Post!
dogweather
I got a little confused by those docs too, and made a mental note to go back and see if I could figure out the difference.
But about the “only use very rarely”, I feel confident shedding some light on that.
Maybe someone will come along and correct me, but I believe that the Elixir ecosystem is fairly opinionated (in a good way) about not catching exceptions/errors. 95% of the time we should just ignore them and let them crash the app. Then, we look at the crashes, which should be only due to programming errors, and fix our bugs.
Said differently, The exceptions are generally things outside of our control that we can’t really program for. And: this is how we should design our own code: to use {:ok, :error} for business logic errors, and reaching for raising exceptions for unsalvageable inconsistencies.
Most Liked
josevalim
Semantically:
-
A
throwis meant to be caught by you (typically within the same module that throws), can be any term -
An
erroris when something goes wrong (typically not rescued), it is an exception in Elixir -
An
exitis when a process is crashing (typically not caught), can be any term
throws are handled by catchs, errors are handled by rescues. If I had a magic wand, exit would not be part of the language, especially because it is often mixed with the separate exit signal, but it exists in Erlang, so we have to support it, hence the catch kind, reason -> notation.
PRs to improve the docs are always welcome.
mudasobwa
I would treat try/catch as a control flow (goto-like,) while try/rescue as handling an exceptional situation.
al2o3cr
rescue is a shorthand, mostly. catch can do its job, but there’s more boilerplate and some of the shapes aren’t as nice:
try do
1 + :foo
rescue
e ->
IO.puts "OH NO #{inspect(e)}"
end
(prints OH NO %ArithmeticError{message: "bad argument in arithmetic expression"})
versus
try do
1 + :foo
catch
:error, e ->
IO.puts "OH NO #{inspect(e)}"
end
which prints OH NO :badarith
Using catch in this way also means that Erlang errors are not transformed into Elixir exceptions - note the different inspect output for the two cases.
Last Post!
gregvaughn
This is oversimplified, but throw/catch comes from Erlang. The payload can be any Erlang term (usually a tuple) and it relies on historical implicit conventions of how to use it. Elixir uses raise/rescue to encode/decode an Exception struct as the payload as an explicit convention.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex









