Hi Folks,
I am using dialyzer to do some static analysis on my code. So far, everything has been going great, but I am running into a warning that I don’t know how to parse. The warning is this:
posts_controller.ex:1: The call 'Elixir.CRM.PostController':authenticate(_@5::#{},[]) will never return since the success typing is (#{},#{}) -> #{} and the contract is ('Elixir.Plug.Conn':t(),#{}) -> 'Elixir.Plug.Conn':t()
Someonne mentioned that this is likely due to an dialyzer overspec setting being on. However, the documentation for dialyxir indicates that it no longer sets any of those flags (and I’m not sure that it ever set the overspec flag).
I tried changing the spec to something less strict, such as a map, but I still got the warning. Then, I tried making the function more strict (by making it pattern match on a %Plug.Conn{}
struct, but that also gave the warning.
Anyway, would like to know what you folks think is the problem, and the potential solution.
Here is my code:
defmodule CRM.PostController do
@moduledoc false
use CRM.Web, :controller
alias CRM.Authentication
plug :authenticate when action in [:index]
def index(conn, _params) do
render(conn, "index.html")
end
@spec authenticate(Plug.Conn.t, map) :: Plug.Conn.t
def authenticate(conn, params) do
Authentication.require_authenticated(conn, params)
end
end
Finally, here is the definition of authentication:
defmodule CRM.Authentication do
@moduledoc ~S"""
Defines a set of helper plugs for authentication.
"""
import Phoenix.Controller, only: [put_flash: 3, redirect: 2]
import Plug.Conn, only: [get_session: 2, assign: 3, halt: 1]
@doc ~S"""
Ensures that a user is authenticated, or halts the connection.
"""
@spec require_authenticated(Plug.Conn.t, map) :: Plug.Conn.t
def require_authenticated(%{assigns: %{current_user: nil}} = conn, _params) do
conn
|> put_flash(:error, "You must be logged in to access that page.")
|> redirect(to: "/")
|> halt
end
def require_authenticated(%{assigns: %{current_user: _user}} = conn, _params) do
conn
end
end