11

So a conversation arose for me and some friends around a passage in this page of Elixir documentation.

In Elixir, a value can be thrown and later be caught. throw and catch are reserved for situations where it is not possible to retrieve a value unless by using throw and catch.

Those situations are quite uncommon in practice except when interfacing with libraries that do not provide a proper API.

Which situations would require using try/throw/catch vs. try/rescue? Is this for interfacing with some existing Erlang libraries? The sample on the page shows Elixir code which is what I find a bit confusing.

What would be the "proper API" that I should be looking for? I mean would this be a protocol?

Onorio Catenacci
  • 14,928
  • 14
  • 81
  • 132
  • The Dave Thomas book gives a few examples: the database going down or a name server failing to respond, or failing to open a configuration file whose name is fixed. – GavinBrelstaff Mar 16 '16 at 14:29
  • Why would those situations require a catch rather than a rescue? That's what I'm asking--what's the difference there? – Onorio Catenacci Mar 16 '16 at 15:06
  • 1
    I should have researched a bit further. It looks like this question was sort of asked and answered on the Elixir Core List a while ago: https://groups.google.com/d/topic/elixir-lang-core/0eG2BqKfC_U/discussion – Onorio Catenacci Mar 16 '16 at 15:53

1 Answers1

15

I consider raise/rescue to be explicitly about exception handling - meaning completely unexpected situation where you want to have a stacktrace and a programmer looking at it. It may happen because of multiple things - programmer error, wrong environment, etc, but user providing invalid data is not one of those cases.

Throw/catch is useful in places where you have expected failures, but you still want to use the non-local control flow that is offered by raise/rescue. This also allows you to skip the cost of building a stacktrace that is sometimes considerable. Classic examples are:

My rule of thumb for choice of one over the other would be that catch is essential to properly functioning program while rescue should be removable in the general case. Of course there are exceptions to that rule, but I think it's a useful first-level distinction.

michalmuskala
  • 11,028
  • 2
  • 36
  • 47
  • 4
    Given your comment and Jose's answer--does raise generate a stack trace and throw does not? Is that one of the salient differences? – Onorio Catenacci Mar 16 '16 at 16:10
  • Referencing master branches in answers is problematic in that master branches are expected to change over time. Consider revising these links to reference a specific commit sha, like the third transactions example – colincr Aug 22 '22 at 21:14