LauraBeatris

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

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.

Where Next?

Popular in Questions Top

qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
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
mgjohns61585
Could someone help me? I’m making my first elixir program, number guessing game. I can’t figure out how to convert the user’s guess from ...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call t...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
dotdotdotPaul
Okay, I’m having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I’m sure I’...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New

Other popular topics Top

sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 42920 311
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 41539 114
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30877 112
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
hariharasudhan94
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
RisingFromAshes
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
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New

We're in Beta

About us Mission Statement