Dialyzer warning: has no local return

Hope to get some advice:

defmodule MyWeb.PageView do

  use MyWeb, :view

  def current_timeinterval do
    {:ok, first_day} =
      Timex.beginning_of_month(Timex.now(Timex.Timezone.local()))
      |> Timex.format("{D} {Mfull} {YYYY}")
    {:ok, last_day} =
      Timex.end_of_month(Timex.now(Timex.Timezone.local()))
      |> Timex.format("{D} {Mfull} {YYYY}")
    "#{first_day} - #{last_day}"
  end
end

My intention is to embed the output of this current_timeinterval() function in a EEx template and it will result in the value “1 December 2020 - 30 December 2020” as of now being displayed on the page, new.html

However Dialyzer generates this error:
“Function new.html/1 has no local return”
“Function current_timeinterval/0 has no local return.”

followed by

"message": "The function call will not succeed.\n\nTimex.now(\n  {:error, _}\n  | %{\n      :__struct__ => Timex.AmbiguousTimezoneInfo | Timex.TimezoneInfo,\n  ..."

Any thoughts on what I am probably doing wrong? Many thanks.

Timex.Timezone.local does not return a value that would be understood by Timex.now, at least by the type information availble to dialyzer.

Accepted by new is String.t() | tz_offset() | :utc | :local (where tz_offset is -14..12), while local returns Timex.TimezoneInfo.t() | Timex.AmbiguousTimezoneInfo.t() | {:error, term()}.

1 Like

Timex.now/1 has a spec that’s narrower than what it actually supports:

But Timex.Timezone.convert/2 doesn’t have the correct spec either: it adds TimezoneInfo.t() but omits the non-String parts of valid_timezone

Consider using Timex.local/0 to sidestep this issue entirely.

1 Like

Thank you NobbZ and al2o3cr. I am absolutely mortified being stumbled by such a simple error.

1 Like