StragaSevera

StragaSevera

How do I handle GenServer calls with Dialyzer?

Let’s image that I have a behaviour:

defmodule Bylins.Parser.API do
  @behaviour __MODULE__

  @callback get_page(integer()) :: {:ok, String.t()}
end

And I have a GenServer implementing this behaviour:

defmodule Bylins.Parser.ReqAPI do
  alias Bylins.Parser.API
  use GenServer
  @behaviour API
# ...
  @impl true
  def get_page(i) do
    GenServer.call(__MODULE__, {:get_page, i})
  end

  @impl true
  def handle_call({:get_page, i}, _from, req) do
    {:reply, :error, req}
  end
end

This implementation is clearly wrong, because get_page is obliged to return {:ok, String.t() and not :error. But Dialyzer does not catch this!
Although I can manually type the handle_call method, in the future, if the behaviour changes its spec, I can forget to update the spec on handle_call, leading to errors. And there can be usability problems if I add multiple handle_calls to this module - if I understand correctly, I will be forced to cram all of possible options into one spec.

Is there a better way to handle this situation? =-)

First Post!

al2o3cr

al2o3cr

Dialyzer doesn’t “see” through the message-passing that GenServer.call does, so it will not spot this error.

In general, the behavior of handle_call isn’t constrained by its type anyways, since it could call GenServer.reply/2 and always return {:noreply, state}

Where Next?

Popular in Questions Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
LegitStack
I’m hoping you guys can give me some general advice and perhaps code examples if you’re feeling up to it. I’m very interested in Elixir,...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
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
wernerlaude
In AR this is so simple @articles = current_user.articles How to do in Ecto? def index(conn, _params) do current_user = conn.assig...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

Other popular topics Top

yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New

We're in Beta

About us Mission Statement