marisradu

marisradu

How can I DRY out this code more (Plug.Conn, with statement)

Disclaimer: I’m new (still learning) elixir.
Can’t figure how to DRY this code out, I would like to capture the “message” from all blocks and then send the response and halt the connection.

Original code:

def call(conn, _) do
    case some_function(conn) do
      {:ok, response} ->
        put_private(conn, :my_app, %{my_key: response})

      {:error, :error_1 ->
        conn
        |> put_resp_content_type("application/json")
        |> send_resp(403, "Message for error 1")
        |> halt

      {:error, :error_2} ->
        conn
        |> put_resp_content_type("application/json")
        |> send_resp(403, "Message for error 2")
        |> halt

      _ ->
        conn
        |> put_resp_content_type("application/json")
        |> send_resp(403, "Generic message")
        |> halt
    end
  end

I wanted to put everything in a with statement like:

with {:ok, response} <-  some_function(conn) do
     put_private(conn, :my_app, %{my_key: response})
else
     {:error, :error_1} ->
        message = "Message for error 1"
     {:error, :error_2} ->
        message = "Message for error 2"
      _ ->
        message = "Generic message"
    end

I’m pretty sure there is a better way to capture the “message” and also not sure where to put the “response” as inside the “else” clause will need to put it for all clauses, outside will also be triggered if there is no error.

conn
|> put_resp_content_type("application/json")
|> send_resp(403, message)
|> halt

Any hint or constructive criticism in case you think I’m going in the wrong direction will be appreciated.
Thanks.

Most Liked

mbuhot

mbuhot

When in doubt, use more functions :smile:

def call(conn, _) do
  with {:ok, response} <- some_function(conn) do
    put_private(conn, :my_app, %{my_key: response})
  else
    err -> 
      message = error_message(err)
      conn
      |> put_resp_content_type("application/json")
      |> send_resp(403, message)
      |> halt
  end
end
    
defp error_message({:error, :error_1}), do: "Message for error 1"
defp error_message({:error, :error_2}), do: "Message for error 2"
defp error_message(_), do: "Generic message"
idi527

idi527

I don’t see much reason to use with when a flat case would be enough (as in your case).

LostKobrakai

LostKobrakai

I’m mostly of the same opinion, but with might communicate a bit more the monad-like success/error railway-ing while case is a bit more “equal cases” in it’s semantics. Especially in plugs where one branch does halt the pipeline I see myself more drawn to using with.

LostKobrakai

LostKobrakai

Using with was already a good idea, but sometimes just using one flow control type is just not enough:

def call(conn, _) do
	with {:ok, response} <- some_function(conn) do
		put_private(conn, :my_app, %{my_key: response})
	else
		err -> 
			message =
			  case err do
					{:error, :error_1} -> "Message for error 1"
					{:error, :error_2} -> "Message for error 2"
					_ -> "Generic message"
				end

			conn
			|> put_resp_content_type("application/json")
			|> send_resp(403, message)
			|> halt
	end
end
marisradu

marisradu

Damn … did do that, but missed to check in the preview pane.
Definitely going to get a strong coffee now.

Thanks for the notification.

Where Next?

Popular in Questions Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New

Other popular topics Top

pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

We're in Beta

About us Mission Statement