ycherniavskyi
Collect all function return tuples in the module with macro and provide access to them with a helper function
Let’s say I have next controller where {:error, _, _} action result processed by FallbackController:
defmodule SomeProjectWeb.Api.V1.SessionController do
use SomeProjectWeb, :controller
alias SomeProject.Session
alias SomeProject.Session.Otp
alias SomeProjectWeb.Api.V1.CastAndValidateRenderError
alias SomeProjectWeb.Api.V1.FallbackController
alias SomeProjectWeb.Api.V1.{CommonSchema, SessionSchema}
plug(OpenApiSpex.Plug.CastAndValidate, render_error: CastAndValidateRenderError)
action_fallback(FallbackController)
tags(["session"])
def action(conn, _) do
apply(__MODULE__, action_name(conn), [conn, conn.params, conn.body_params])
end
operation(:otp_create,
summary: "otp_create summary",
description: "otp_create description",
requestBody: {
"request body description",
"application/json",
SessionSchema.OtpCreateRequest,
required: true
},
responses: [
ok: {
"ok description",
"application/json",
SessionSchema.OtpCreateResponse
},
unauthorized: "...",
unprocessable_entity: {
"Unprocessable Content, ...",
"application/json",
%Schema{
allOf: [
CommonSchema.ErrorResponse,
%Schema{
type: :object,
properties: %{
code: %Schema{
enum: [
:no_otp_delivery_channel,
:runout_signup_account
]
}
}
}
]
}
},
internal_server_error: {
"Internal Server Error, ...",
"application/json",
%Schema{
allOf: [
CommonSchema.ErrorResponse,
%Schema{
type: :object,
properties: %{
code: %Schema{
enum: [
:external_api,
:demo_account_manager
]
}
}
}
]
}
}
]
)
def otp_create(conn, _params, %{user_email: email} = _body_params) do
case SomeProject.DemoAccountManager.retrieve(email) do
{:ok, i_account} ->
case SomeProject.ExternalApi.create_otp(i_account) do
{200, %{"success" => 1, "type" => "email", "from" => email}} ->
otp = Session.create_otp(%{i_account: i_account, demo: true})
render(conn, otp_id: otp.id, type: "email", from: email)
{500, %{"faultcode" => "channel-error"}} ->
{:error, :unprocessable_entity, :no_otp_delivery_channel}
_ ->
{:error, :internal_server_error, :external_api}
end
{:error, :runout} ->
{:error, :unprocessable_entity, :runout_signup_account}
{:error, _} ->
{:error, :internal_server_error, :demo_account_manager}
end
end
end
For now, I manually sync possible error codes for each result with relative result schema. That is diffidently not convenient and will lead to unsync in the future.
I want to implement some type of module macro that will collect and group all its functions :error results and introduce the helper function to access them.
So I could replace:
internal_server_error: {
"Internal Server Error, ...",
"application/json",
%Schema{
allOf: [
CommonSchema.ErrorResponse,
%Schema{
type: :object,
properties: %{
code: %Schema{
enum: [
:external_api,
:demo_account_manager
]
}
}
}
]
}
}
with:
internal_server_error: {
"Internal Server Error, ...",
"application/json",
%Schema{
allOf: [
CommonSchema.ErrorResponse,
%Schema{
type: :object,
properties: %{
code: %Schema{
enum: error_codes(:otp_create, :internal_server_error)
}
}
}
]
}
}
(for sure such the final helper function could produce a more significant piece of repetitive code, but here I want to highlight its core functionality)
What is the best way to implement such functionality?
Popular in Questions
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
Hi guys, i’m new in the Elixir world, and i have to say, that i love it!
i’m having some problem to understand anonymous functions with ...
New
Hi all,
I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage.
I’m trying to use Postgres...
New
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 I...
New
I have a super simple question about elixir - how would I take a file like this
foo
bar
baz
and output a new file that enumerates th...
New
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
Hello!
Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
Hi!
Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
Other popular topics
lets say i have a sample like
a = 20; b = 10;
if (a > b) do
{:ok, "a"}
end
if (a < b) do
{:ok, b}
end
if (a == b) do
{:ok, "equa...
New
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help.
Where are they similar?
Where do they differ the m...
New
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
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
New
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition)
It’s been a while since we first asked this, I...
New
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









