LauraBeatris
How to apply a guard in a function
The goal of this post is to get some guidance on how to apply guards to the function below. I’m struggling to make it work with the when keyword, and had to place a giant if block to make the logic work.
Giving more context around the function: Either a ‘connection’, ‘organization’, ‘domain’, or ‘provider’ args should be provided, otherwise the function shouldn’t be executed.
This is how it looks like by using a if
@doc """
Generates an OAuth 2.0 authorization URL.
"""
@spec get_authorization_url(map()) :: {:ok, String.t()} | {:error, String.t()}
def get_authorization_url(params) do
if is_map_key(params, :connection) or is_map_key(params, :organization) or
is_map_key(params, :redirect_uri) do
if is_map_key(params, :domain) do
Logger.warn(
"The `domain` parameter for `get_authorization_url` is deprecated. Please use `organization` instead."
)
end
defaults = %{
client_id: WorkOS.config() |> Keyword.take([:client_id]),
response_type: "code"
}
query =
defaults
|> Map.merge(params)
|> Map.take(
[
:domain,
:provider,
:connection,
:organization,
:client_id,
:redirect_uri,
:state,
:domain_hint,
:login_hint
] ++ Map.keys(defaults)
)
|> URI.encode_query()
base_url = WorkOS.config() |> Keyword.take([:base_url])
{:ok, "#{base_url}/sso/authorize?#{query}"}
else
{:error, "Invalid params"}
end
end
I tried to do the same approach with a guard:
@spec get_authorization_url(map()) :: {:ok, String.t()} | {:error, String.t()}
def get_authorization_url(params) when is_map_key(params, :connection) or is_map_key(params, :organization) or
is_map_key(params, :redirect_uri) do
if is_map_key(params, :domain) do
Logger.warn(
"The `domain` parameter for `get_authorization_url` is deprecated. Please use `organization` instead."
)
end
defaults = %{
client_id: WorkOS.config() |> Keyword.take([:client_id]),
response_type: "code"
}
query =
defaults
|> Map.merge(params)
|> Map.take(
[
:domain,
:provider,
:connection,
:organization,
:client_id,
:redirect_uri,
:state,
:domain_hint,
:login_hint
] ++ Map.keys(defaults)
)
|> URI.encode_query()
base_url = WorkOS.config() |> Keyword.take([:base_url])
"#{base_url}/sso/authorize?#{query}"
end
However, I’m getting the following Dialyzer error: “The @spec for the function does not match the success typing of the function.” - what is it trying to infer here regarding the “does not match the success typing”?
Should another function clause be declared to handle the case where none of those args are provided?
Marked As Solved
stefan_z
Hi @LauraBeatris,
What I can see from your guard example is that you definitely miss default get_authorization_url /1 function that will be called when one of the guards is false.
def get_authorization_url(_params), do: {:error, "Invalid params"}
Also specification for a function says that return types are {:ok, String.t()} | {:error, String.t()} but your function only returns string instead of tuple.
Popular in Questions
Other popular topics
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








