Phoenix: Dialyzer warnings on lib/phoenix/router.ex

Created on 6 Feb 2018  路  3Comments  路  Source: phoenixframework/phoenix

Environment

  • Elixir version (elixir -v):
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Elixir 1.6.0 (compiled with OTP 20)
  • Phoenix version (mix deps): 1.3.0
  • NodeJS version (node -v): v6.10.0
  • NPM version (npm -v): 4.3.0
  • Operating system: Mac OS X

Expected behavior

Dialyzer should not emit any warnings on a clean project.

Actual behavior

Here are the steps to reproduce the Dialyzer warnings:

  1. mix phx.new hello --no-html
  2. Edit mix.exs file to include {:dialyxir, "~> 0.5.1", only: :dev, runtime: false} in the list of deps and dialyzer: [flags: [:unmatched_returns, :error_handling, :race_conditions, :underspecs]] in the project config
  3. mix deps.get
  4. mix dialyzer
hello $ mix dialyzer
==> dialyxir
Compiling 5 files (.ex)
Generated dialyxir app
==> hello
Compiling 10 files (.ex)
Generated hello app
Checking PLT...
[:asn1, :compiler, :connection, :cowboy, :cowlib, :crypto, :db_connection,
 :decimal, :ecto, :eex, :elixir, :gettext, :kernel, :logger, :mime, :phoenix,
 :phoenix_ecto, :phoenix_pubsub, :plug, :poison, :poolboy, :postgrex,
 :public_key, :ranch, :runtime_tools, :ssl, :stdlib]
Finding suitable PLTs
Looking up modules in dialyxir_erlang-20.2.2_elixir-1.6.0_deps-dev.plt
Looking up modules in dialyxir_erlang-20.2.2_elixir-1.6.0.plt
Finding applications for dialyxir_erlang-20.2.2_elixir-1.6.0.plt
Finding modules for dialyxir_erlang-20.2.2_elixir-1.6.0.plt
Checking 391 modules in dialyxir_erlang-20.2.2_elixir-1.6.0.plt
Finding applications for dialyxir_erlang-20.2.2_elixir-1.6.0_deps-dev.plt
Finding modules for dialyxir_erlang-20.2.2_elixir-1.6.0_deps-dev.plt
Copying dialyxir_erlang-20.2.2_elixir-1.6.0.plt to dialyxir_erlang-20.2.2_elixir-1.6.0_deps-dev.plt
Looking up modules in dialyxir_erlang-20.2.2_elixir-1.6.0_deps-dev.plt
Checking 391 modules in dialyxir_erlang-20.2.2_elixir-1.6.0_deps-dev.plt
Adding 666 modules to dialyxir_erlang-20.2.2_elixir-1.6.0_deps-dev.plt
Starting Dialyzer
dialyzer args: [
  check_plt: false,
  init_plt: '/Users/fertapric/Desktop/hello/_build/dev/dialyxir_erlang-20.2.2_elixir-1.6.0_deps-dev.plt',
  files_rec: ['/Users/fertapric/Desktop/hello/_build/dev/lib/hello/ebin'],
  warnings: [:unmatched_returns, :error_handling, :race_conditions, :underspecs,
   :unknown]
]
done in 0m2.04s
lib/phoenix/router.ex:2: Function call/2 has no local return
done (warnings were emitted)

It seems to be related to the --no-html flag, because doing the same withmix phx.new hello does not emit any warning.

Most helpful comment

For those looking for a solution to silence the warning:

defmodule MyAppWeb.Router do
  use MyAppWeb, :router
  @dialyzer {:no_return, {:__checks__, 0}} # <-- Add this line

  ---
end

Cheers!

All 3 comments

PRs are appreciate on this front. :) We don't plan to track the dialyzer warnings ourselves for now.

I've been investigating the issue and it pops up when no routes are defined. It seems the call/2 function defined by the router can only raise exceptions due to the generated code:

def call(conn, _opts) do
  conn
  |> prepare()
  |> __match_route__(conn.method, Enum.map(conn.path_info, &URI.decode/1), conn.host)
  |> Phoenix.Router.__call__()
end

def __match_route__(conn, _method, _path_info, _host) do
  raise NoRouteError, conn: conn, router: __MODULE__
end

Returning Plug.Conn is impossible then.

To explain why this fails only when the --no-html is provided we need to take a look at the generators. By default, the generators create a controller (PageController) and an entry in the router get "/", PageController, :index, but those are not created when passing the --no-html flag.

Unfortunately, I don't know how to fix this 馃槥

Fortunately, this is quite an edge case and maybe it does not need to be addressed.

For those looking for a solution to silence the warning:

defmodule MyAppWeb.Router do
  use MyAppWeb, :router
  @dialyzer {:no_return, {:__checks__, 0}} # <-- Add this line

  ---
end

Cheers!

Was this page helpful?
0 / 5 - 0 ratings