#Help with building an error type (question at the bottom)

1 messages · Page 1 of 1 (latest)

pale ether
#

Hey, i just read there is a better way to handle errors than this:

with {:service, {:ok, resp}}   <- {:service, call_service(data)},
     {:decode, {:ok, decoded}} <- {:decode, Jason.decode(resp)},
     {:db, {:ok, result}}      <- {:db, store_in_db(decoded)} do
  :ok
else
  {:service, {:error, error}} ->
    # Do something with service error
  {:decode, {:error, error}} ->
    # Do something with json error
  {:db, {:error, error}} ->
    # Do something with db error
end

It says to avoid else blocks in with statements:

defmodule MyApp.Error do
  defexception [:code, :msg, :meta]

  def new(code, msg, meta) when is_binary(msg) do
    %__MODULE__{code: code, msg: msg, meta: Map.new(meta)}
  end

  def not_found(msg, meta \\ %{}) do
    new(:not_found, msg, meta)
  end

  def internal(msg, meta \\ %{}) do
    new(:internal, msg, meta)
  end
end

def main do
  with {:ok, response} <- call_service(data),
       {:ok, decoded}  <- decode(response),
       {:ok, result}   <- store_in_db(decoded) do
    :ok
  end
end

# We wrap the result of Jason.decode in our own custom error type
defp decode(resp) do
  with {:error, e} <- Jason.decode(resp) do
    {:error, Error.internal("could not decode: #{inspect resp}")}
  end
end

I dont quite understand how this works, do i need to create a wrapper for every of my funcions that handles the error case? Thanks

bright ingot
pale ether
bright ingot
#

yes, sometimes better readability comes with tradeoffs

#

you don't have to do it this way, but it is recommended by the community

pale ether
#

like this function call_service, i would have to move it's contents to another function called something like call_service_body and make call_service a wrapper that handles the error

jade aurora
#

if you're doing different things with different errors, don't you want case?

pale ether
#

unmaintanable

jade aurora
#

I think the way you have it is spaghetti. Three cases is not spaghetti.

pale ether
jade aurora
#

you're handling each error differently?