I often find myself having to “tag” my with clauses, often because checking {:ok, _}|{:error, _}
isn’t descriptive enough for error handling,
with {:post, {:ok, post}} <- {:post, fetch_post(id)},
{:meta, {:ok, meta}} <- {:other_data, fetch_post_meta(post)},
{:auth, :ok} <- {:auth, authorize(...)},
do: ...
else
{:post, {:error, reason}} -> show_404_or_whatever()
{:meta, {:error, reason}} -> show_post_but_flag_error_or_something()
{:auth, :unauthorized} -> redirect_to_login()
end
vs
with {:ok, post}} <- fetch_post(id),
{:ok, meta}} <- fetch_post_meta(post),
:ok <- authorize(...),
do: ...
else
# cant tell here if {:error, reason} is for fetch_post or fetch_post_meta
{:error, reason} -> generic_error(reason) #?
:unauthorized -> redirect_to_login()
end
Is this pattern implied in your posts or do you have another solution? Always match on specific reason
values? Maybe you simply structure the rest of the app so it isn’t needed (ie: the call should pass in meta
before we even get to the with or ?).
I don’t find tagging to be that bad, but it does add some noise and it can feel like if you have to tag any, you should tag them all, so even stuff like :ok|:unauthorized
end up getting tagged.
Great posts.