Stok Footage

Continually experimenting with new ideas and techniques — Reconstructing, Developing, Modernising.

A Young Person’s Guide to Dialyzer — How to Ignore Some Errors

With my current level of understanding there are a couple of types of message you can “ignore” when you start your exploration.

no local return” Warnings

A message like Function name/arity has no local return reported for the line containing the head of a function is often caused by a problem somewhere in the function body. In my experience, if you clean up the warnings from the function body successfully then this message should stop being emitted. So I tend to ignore these and look at the warnings indicating “real” problems in the function body.

“Other People’s” Warnings

If you are using other modules from hex.pm then they might not be correctly annotated, and in this case it can be useful to search the web for the message. If the warning is a “known problem” with some external module then it’s possible to tell dialyxir to filter out some of the dialyzer warning messages. The README.md says:

Any line of dialyzer output (partially) matching a line in “dialyzer.ignore-warnings” is filtered.

The way to do this is to add a key/value pair like ignore_warnings: "dialyzer.ignore-warnings" to your project’s mix.exs, and then add the relevant bad lines to the file. If the dialyzer output included:

web/services/creation_service.ex:17: Function create/4 has no local return
web/services/creation_service.ex:39: The call 'Elixir.Ecto.Multi':run(transaction@1::#{'__struct__':='Elixir.Ecto.Multi', 'operations':=[{'create_user',_} | {'gen_password_reset_token',_} | {'register_user_command',_},...], _=>_},'creation_command',creation_command@1::fun((_) -> {'ok',#{'stream':=map()}})) does not have an opaque term of type 'Elixir.Ecto.Multi':t() as 1st argument

and the create/4 function included line 39 then some searching might get you to https://github.com/elixir-ecto/ecto/issues/1882, and it might be reasonable to add this to your dialyzer.ignore-warnings file to eliminate warnings from specific lines:

web/services/creation_service.ex:17
web/services/creation_service.ex:39

Or if you have a particular set of errors you want to filter out everywhere then you could put this in the file:

Function create/4 has no local return
The call 'Elixir.Ecto.Multi':run(transaction@1::#{'__struct__':='Elixir.Ecto.Multi', 'operations':=[{'create_user',_} | {'gen_password_reset_token',_} | {'register_user_command',_},...], _=>_},'creation_command',creation_command@1::fun((_) -> {'ok',#{'stream':=map()}})) does not have an opaque term of type 'Elixir.Ecto.Multi':t() as 1st argument</tt>

It’s not advisable to just ignore everything, but this is a useful way to concentrate on problems over which you have some control.

Caveat

The process which dialyxir uses to filter lines out of the dialyzer output runs the contents of the ignore file (in patterns through code like this:

1
2
3
4
5
6
7
8
9
10
11
        lines = Enum.map(output, &String.trim_trailing/1)

        patterns = pattern
        |> String.trim_trailing("\n")
        |> String.split("\n")
        try do
          cp = :binary.compile_pattern(patterns)
          Enum.filter(lines, &(not String.contains?(&1, cp)))
        rescue
          _ -> output
        end

so if there are any blank lines in the ignore file then no filtering will be done because :binary.compile_pattern considers an empty string to be an argument error.

Tags: ,

Leave a Reply

Your email address will not be published. Required fields are marked *