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?