Dialyzer can never evaluate to 'true' for compiled env var

Need help to resolve the Dialyzer offense

in my code i have

@env Application.compile_env(:my_app, :env)

if @env == :prod, do: ...

Dialyzer complains that The test :dev == :prod can never evaluate to 'true' which is true, because it runs in dev env in which env var always equals :dev.

How should I rewrite this to satisfy Dialyzer? Thanks

1 Like

Dialyzer works on compiled code, so you can push the check to the module scope. E.g.

instead of:

demodule A do
  @env Application.compile_env(:my_app, :env)

  def a do
    if @env == :prod, do: ...
  end
end

You can do:

defmodule A do
  @env Application.compile_env(:my_app, :env)

  if @env == :prod do
    def a do
       ...prod stuff...
    end
  else
    def a do
       ...non prod (dev, test, other) stuff...
    end
  end
end

Dialyzer will have only one of the versions of a function, so it won’t complain.

Caveat: if prod checks have the problem that locally stuff will work fine and dialyze, but then the prod branch will be checked only in prod. Make sure that you also run dialyzer on an artefact compiled with prod

4 Likes

Another variant is to launder the value of @env through the identity function, writing the test as if Function.identity(@env) == :prod, do: ... instead. This avoids the problem of the prod branch only being checked in prod.

4 Likes

Thanks a lot @tomekowal and @jhogberg This is very helpful

1 Like