Dialyzer error with Supervisor.init

Background

I have a GameSupervisor that spins up a process called Game and supervises it. In order to have my code more error free I am also using Dialyzer, but it is giving me some odd errors:

Code

The following is my GameSupervisor, from the book “Functional Web Development with Elixir, OTP, and Phoenix”:

defmodule IslandsEngine.GameSupervisor do
  use Supervisor

  alias IslandsEngine.Game

  #######
  # API #
  #######

  @spec start_link(any) :: Supervisor.on_start
  def start_link(_args), do:
    Supervisor.start_link(__MODULE__, :ok, name: __MODULE__)

  #############
  # Callbacks #
  #############

  @impl Supervisor
  @spec init(:ok) :: {:ok, tuple}
  def init(:ok), do:
    Supervisor.init([Game], strategy: :simple_one_for_one)

end

Problem

This code works fine, but Dialyzer seems to have several issues with it:

The return type {'ok',tuple()} in the specification of init/1 is not a subtype of 'ignore' | {'ok',{{'one_for_all',non_neg_integer(),pos_integer()} | {'one_for_one',non_neg_integer(),pos_integer()} | {'rest_for_one',non_neg_integer(),pos_integer()} | {'simple_one_for_one',non_neg_integer(),pos_integer()} | #{'intensity'=>non_neg_integer(), 'period'=>pos_integer(), 'strategy'=>'one_for_all' | 'one_for_one' | 'rest_for_one' | 'simple_one_for_one'},[{_,{atom(),atom(),'undefined' | [any()]},'permanent' | 'temporary' | 'transient','brutal_kill' | 'infinity' | non_neg_integer(),'supervisor' | 'worker','dynamic' | [atom()]} | #{'id':=_, 'start':={atom(),atom(),'undefined' | [any()]}, 'modules'=>'dynamic' | [atom()], 'restart'=>'permanent' | 'temporary' | 'transient', 'shutdown'=>'brutal_kill' | 'infinity' | non_neg_integer(), 'type'=>'supervisor' | 'worker'}]}}, which is the expected return type for the callback of the 'Elixir.Supervisor' behaviour

Function init/1 has no local return

The call 'Elixir.Supervisor':init(['Elixir.IslandsEngine.Game'],[{'strategy','simple_one_for_one'},...]) breaks the contract ([supervisor:child_spec() | {module(),term()} | module()],[init_option()]) -> {'ok',tuple()}

Which is confusing, because according to the Supervisor.init/2 documentation, my specs should be just fine:

https://hexdocs.pm/elixir/Supervisor.html#init/2

Question

What am I doing wrong?

The strategy simple_one_for_one has been deprecated, see this post

This has been replaced by dynamic_supervisor :slight_smile:

2 Likes

Wow, I knew it had been deprecated, but I didn’t know Dyalizer would complain so vividly about it.
The book I am reading does not mention Dynamic Supervisors (they probably didn’t exist back then) so I guess I will just have to accept it or refactor the code into a newer version like your post suggests.

THanks !!