lib/my_app/accounts/accounts.ex:134: Function authenticate_by_username_password/2 has no local return
def authenticate_by_username_password(username, given_password) do
user = User
|> Repo.get_by(username: username)
|> Repo.preload(:credential)
cond do
user && checkpw(given_password, user.credential.password_hash) ->
{:ok, user}
user ->
{:error, :unauthorized}
true ->
dummy_checkpw()
{:error, :not_found}
end
end
As mentioned in the doc If the struct in the queryable has no or more than one primary key, it will raise an argument error.
Moreover, the return value of get_by/3 could be :
Ecto.Schema.t() |
nil |
no_return()
Does that mean that if an argument error is raised by get_by/3, then the cond block won’t be executed, moreover authenticate_by_username_password/2 return value will be set to type no_return(), which finally makes dialyzer complain like that?
If so, should I try to catch the possible argument error of get_by/3? Or just let it go .
Yes, any exception anywhere that isn’t rescued will result in a non-local return. But thats ok if you have described none() or no_return() in the @spec for your function.
Do you have a @spec for the function? Since Dialyzer is a “success typing” tool it helps if it knows your intention.
Are you also getting Dialyzer warnings on checkpw and dummy_checkpw?
I have added the spec below but I am still getting the warning. @spec authenticate_by_username_password(String.t(), String.t()) :: {:ok, Ecto.Schema.t()} | {:error, atom()} | no_return()
Are there no dialyzer errors in related code at all?
The fact that the Ecto function can raise in some cases shouldn’t matter, when Dialyzer says “no local return” it means none at all. Here I would suspect something is wrong with checkpw.
I do assume you use comeonin with argon2_elixir prior to version 1.3.1? If this is true, please update argon to 1.3.1 and check if the problem persists. It had a bug discussed in #13 which I submitted a fix in #21.
If my assumptions are all wrong, you need to provide more details, as used packages, their versions and probably some bit of code where the warning occurs.
Also due to some problems with elixir LS (it has problems to rebuild typeinfo of deps when necessary or update in dependent files) so to be sure either run dialyxir from the shell or remove your elixir-ls folder and restart the editor (to make the LS restart).