Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

this was really hard to read. let's give it a shot, though.

    @spec my_fn(a::input_type)::{:ok, res::result_type} | {:error, any}

    def my_fn(a) do
      a
      |> get_resource
      |> case do
        {:ok, result} -> result 
        {:error, :recoverable} -> get_alt_resource(a)
        err = {:error, :reallybad} -> throw err
      end
      |> many_more_steps_might_have_similar_pattern

    catch err
      err
    end
However what you presented seems to me to be an antipattern. Sometimes code clarity trumps terseness; in this case the results from get_resource and get_alt_resource are categorically identical. If we are allowed to refactor to be actually sane code and not require everything to be in a single function:

    def my_fn(a) do
      with {:ok, res1} <- resource_wrapper(a),
           {:ok, res2} <- next_step(res1), ...
      case
        #handle errors here.
      end
    end

    @doc """
    fetches resources of type `your-favorite-type` which
    can either come from `get_resource` or `get_alt_resource`
    """
    def resource_wrapper(a) do
      case get_resource(a) do
        ok = {:ok, a} -> ok
        {:error, :recoverable} -> 
           get_alt_resource(a)
           # note with this code if alt_resource 
           # gives you an error tuple you are still 
           # good to go
        err = {:error, :fatal} -> err
      end
    end
seems much more sane


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: