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_call
s 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? =-)