jeremyjh / dialyxir

Mix tasks to simplify use of Dialyzer in Elixir projects.
Apache License 2.0
1.7k stars 140 forks source link

Exception when starting new dialyzer release candidate #190

Closed dragonwasrobot closed 6 years ago

dragonwasrobot commented 6 years ago

Hi, I wanted to try out your release candidate, but I get the following error, while running Elixir 1.6.3 and OTP 20:

Starting Dialyzer
[
  check_plt: false,
  init_plt: '/<path-to-project>/_build/dev/dialyxir_erlang-20.1_elixir-1.6.3_deps-dev.plt',
  files_rec: ['/<path-to-project>/_build/dev/lib/meetings/ebin'],
  warnings: [:unknown],
  format: nil,
  raw: nil
]
** (throw) {:error, :lexing, 'Elixir.GenStage'}
    lib/dialyxir/pretty_print.ex:8: Dialyxir.PrettyPrint.lex/1
    lib/dialyxir/pretty_print.ex:33: Dialyxir.PrettyPrint.pretty_print/1
    lib/dialyxir/warnings/unknown_function.ex:15: Dialyxir.Warnings.UnknownFunction.format_long/1
    lib/dialyxir/formatter.ex:77: Dialyxir.Formatter.format_warning/2
    lib/dialyxir/formatter.ex:170: anonymous fn/2 in Dialyxir.Formatter.filter_warnings/2
    (elixir) lib/enum.ex:2955: Enum.reject_list/2
    lib/dialyxir/formatter.ex:25: Dialyxir.Formatter.format_and_filter/3
    lib/dialyxir/dialyzer.ex:36: Dialyxir.Dialyzer.Runner.run/2
asummers commented 6 years ago

Hmmm that's strange, that should be rescuing and throwing appropriately.

asummers commented 6 years ago

How are you starting it? mix dialyzer? Looking at the code, that throw is being caught:

      {:error, :lexing, warning} ->
        message = """
        Failed to lex warning:
        #{inspect(warning)}
        """

        wrap_error_message(message, dialyzer_warning)
dragonwasrobot commented 6 years ago

just running mix dialyzer.

where do you find the above clause?

looks like this block:

  defp lex(str) do
    try do
      {:ok, tokens, _} = :struct_lexer.string(str)
      tokens
    rescue
      _ ->
        throw({:error, :lexing, str})
    end

called from

@spec pretty_print(String.t()) :: String.t()
def pretty_print(str) do
    parsed =
      str
      |> to_charlist()
      |> lex()
      |> parse()

and I can't see anything calling pretty_print up through the stacktrace which such a clause.

asummers commented 6 years ago

formatter.ex calls format_long in the UnknownFunction warning module, which eventually calls pretty_print/1. Since it's being thrown in the code you posted and then caught with the code I posted, that should just be ok... but clearly it isn't for some reason.

Kick off point:

lib/dialyxir/formatter.ex:77: Dialyxir.Formatter.format_warning/2

I'll look into making that code even more defensive by adding a rescue after the catches. I won't be able to take care of that til later this evening so PRs are very welcome =)

Probably just something like:

rescue 
  e ->
    message = """
    Unknown error occurred: #{inspect(e)}
    """
   wrap_error_message(message, dialyzer_warning)
end

below all the catches. Might indicate the actual problem, too.

dragonwasrobot commented 6 years ago

No stress mate. Don't think I'll have time to look at doing a PR right now :/

asummers commented 6 years ago

@dragonwasrobot Added a PR to help guard. Mind trying that SHA? Is it a public repo by chance?

jeremyjh commented 6 years ago

I think that PR will solve this, as its an Erlang error but @dragonwasrobot do you mind try with this ref in your deps?

{:dialyxir, git: "https://github.com/jeremyjh/dialyxir", ref: "ac7d22c30b54396940a0763fb8f73687fd3b01ca",  runtime: false}

eta: and by solve I mean give us a good error message regarding the lexing failure...

dragonwasrobot commented 6 years ago

Hi, the repo in which the error occurs in private. I'll try the above ref tomorrow and see if it produces a better error.

axelson commented 6 years ago

Not the original poster but I do get a similar error when running on 1.0.0-rc.0:

** (throw) {:error, :lexing, 'Elixir.MyApp.SomeModule.Atom'}

But everything appears to work fine on ac7d22c30b54396940a0763fb8f73687fd3b01ca

dragonwasrobot commented 6 years ago

It seems to be working - though weird that the bug disappeared - it now outputs:

Starting Dialyzer
[
  check_plt: false,
  init_plt: '<path/to/project>/_build/dev/dialyxir_erlang-20.1_elixir-1.6.3_deps-dev.plt',
  files_rec: ['<path/to/project>/_build/dev/lib/meetings/ebin'],
  warnings: [:unknown],
  format: nil,
  raw: nil
]
Total errors: 21, Skipped: 2
done in 0m2.0s
:0:unknown_function
Function GenStage.call/3 does not exist.
________________________________________________________________________________
:0:unknown_function
Function GenStage.cast/2 does not exist.
________________________________________________________________________________
lib/helpers/web.ex:167:pattern_match
The pattern
443

can never match the type
8260
________________________________________________________________________________
lib/helpers/web.ex:168:pattern_match
The pattern
80

can never match the type
8260
________________________________________________________________________________
lib/messaging/registry.ex:106:overlapping_contract
Overloaded contract for Meetings.Messaging.Registry.handle_info/2 has
overlapping domains; such contracts are currently unsupported and
are simply ignored.

...

which I'm guessing is the new dialyzer format :)

Thanks for the quick response and help 👍

jeremyjh commented 6 years ago

Thanks!