eidge

eidge

Dialyzer - Function has no local return

Hello guys,

When running dialyzer on this function, it complains that the function get has no local return and that build_forecast will never be called.

 def get(%Params{} = params, options \\ []) do
    http_options = Keyword.merge([timeout: 20000], options)
    file_url = PathBuilder.path_for(params)
    case fetch(file_url, http_options) do
      {:ok, forecast_grib2} -> {:ok, build_forecast(params, forecast_grib2)}
      {:error, explanation} -> {:error, explanation}
    end
  end
  defp build_forecast(params, grib2) do
    %__MODULE__{
      params: params,
      data: grib2
    }
  end

I can’t quite understand what it is trying to tell me, as I manually tested and build_forecast gets called.

Full file here:

Any ideas?

Thanks

Most Liked

sasajuric

sasajuric

Author of Elixir In Action

Usually, when you see a has no local return, it means that the cause is an error deeper in the stack. It should be one of the subsequently reported errors.

In this case, your error is The call 'Elixir.Timex':to_date(#{}) breaks the contract ('Elixir.Timex.Convertable') -> 'Elixir.Timex.Date':t() | {'error',term()}

If you look closer, and keep in mind that dialyzer uses Erlang syntax, you can see that you’re passing a map (#{}), while the contract expects 'Elixir.Timex.Convertable'. In Erlang, single quotes denote an atom, so in Elixir syntax this means that according to typespec, Timex.to_date expects Timex.Convertable. I.e. it expects an alias constant, and not a map (which is probably a struct). In other words, a typespec of Timex.to_date is wrong, since the function takes a struct as the first argument (a thing to convert).

Looking at the master, I actually see that the typespec is correct, but it seems that the fix has been done recently. Perhaps you’re not using the latest version, or otherwise it’s not pushed to hex. If that’s the case, you can try using the latest master from GitHub.

22
Post #5
sasajuric

sasajuric

Author of Elixir In Action

Upgrading to Timex 2.2.1 will fix all issues. Once I updated the dep, I rebuilt the code, removed the PLT, generated it again, and there were no errors. I’m not familiar with dialyxir, so not sure if there’s a better way of refreshing PLT.

The root cause of the second error was again a malformed spec in older Timex. The place in your code that triggered it is here. Since Timex spec was wrong, Dialyzer concluded it will always fail, and hence all that call this function unconditionally will also always fail.

It’s unfortunate that dialyzer didn’t report this error, and I’m not quite sure why. Either way, I’ve traced it by starting from get/2 and commenting out parts of it until I narrowed it down to PathBuilder.path_for. A quick glance at PathBuilder revealed the usage of Timex so I suspected that might be the culprit. Substituting the line in question with an empty string "" removed the error, so it was clear that the problem was indeed in Timex. A quick look at its spec in the deps folder confirmed it.

As I said, the required fixes are already done here, so all you need to do is use the more recent version of Timex, rebuild your PLT, and you should be fine.

eidge

eidge

Just added you!

Thank you so much :slight_smile: The community is a big part of why I’m having great fun with Elixir.

eidge

eidge

That’s very reasonable timing :stuck_out_tongue:

Thanks for the quick response. Guess I’m still getting used to tracking weird errors in Elixir.

Mistery solved :slight_smile:

sudostack

sudostack

Check this post out. I’ve not tried Dialyzer yet, but was just reading about it: http://learningelixir.joekain.com/elixir-type-safety/

Where Next?

Popular in Questions Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
Phillipp
Hey, I have a NanoPi-M3 and try to install Elixir on their Ubuntu image. I followed the Raspberry Pi installation instructions from the ...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
Mooodi
Given a string, how can I get access to its character by index? Enum.at("my_string", 2) doesn't work. Or rather, not char, but a substr...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New

Other popular topics Top

pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
273 38985 115
New

We're in Beta

About us Mission Statement