Which Situations Require Throw/Catch In Elixir?

后端 未结 1 606
情话喂你
情话喂你 2021-01-02 03:59

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

1条回答
  •  迷失自我
    2021-01-02 04:22

    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:

    • 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

    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.

    0 讨论(0)
提交回复
热议问题