I found an interesting piece of code that doesn’t pass Dialyzer check in application I work on. I was able to narrow it down into a pretty simple example:
defmodule DialyzerFail do
def call(condition, number) do
with {:ok, :good} <- first_check(condition),
{:ok, :nice} <- second_check(number) do
true
else
error ->
case error do
{:error, :bad} ->
false
{:error, :ugly} ->
notify_ugly(number)
false
end
end
end
def first_check(condition) do
if condition, do: {:ok, :good}, else: {:error, :bad}
end
def second_check(number) do
if number > 1, do: {:ok, :nice}, else: {:error, :ugly}
end
def notify_ugly(_number), do: nil
end
For this code, Dialyzer fails with:
lib/test.ex:9:pattern_match
The pattern can never match the type.
Pattern:
{:error, :bad}
Type:
{:error, :ugly}
________________________________________________________________________________
lib/test.ex:12:pattern_match
The pattern can never match the type.
Pattern:
{:error, :ugly}
Type:
{:error, :bad}
Now, I understand how I could rewrite this code to both look better and appease Dialyzer, but I also would like to understands why it seems to not understand what’s going on in the example I gave.