Fl4m3Ph03n1x
Elixir in Action Application structure is wrong
Background
I have a project that I have recently converted to run as an OTP application. Upon doing this I came back to the “Elixir in Action” book and replay the same steps - but I found something is wrong in the book.
Code
This is how @sasajuric defines an Application (I have added typespec for calrity):
defmodule Todo.Application do
use Application
@impl Application
@spec start(any, any) :: Supervisor.on_start
def start(_, _) do
Todo.System.start_link()
end
end
Simple enough. Todo.System is a simple supervisor:
defmodule Todo.System do
@spec start_link() :: Supervisor.on_start
def start_link do
Supervisor.start_link([...children...], strategy: :one_for_one)
end
end
Problem
At first glance it seems like everything is as it should be. But dialyzer pointed me a problem:
The return type ‘ignore’ in the specification of start/2 is not a subtype of {‘error’,} | {‘ok’,pid()} | {‘ok’,pid(),}, which is the expected return type for the callback of the ‘Elixir.Application’ behaviour(undefined)
This all means that what Todo.System.start_link returns (Supervisor.on_start which expands to something similar to{:ok, pid} | :ignore | {:error, any}) is not compatible with what Todo.Application.start should return: :ok | {:error, term}.
Now, I am not sure what consequences this can have in the long term. The apps launch for now, but this may change on latter updates.
Am I missing something?
But maybe I am missing something? Maybe dialyzer is not smart enough to see some hidden compatibility going on and I am just crying wolf for nothing. What do you think? Is my analysis correct?
On the other hand, if this is in fact wrong, it would be nice if the author could issue a fix (perhaps in the 3rd edition
)
Marked As Solved
sasajuric
I personally wouldn’t bother. Returning :ignore from the top-level supervisor is a bug, and so it’s not something I wouldn’t deal with in the code, since either way the app won’t start, and the original error message is IMO clear enough.
Also Liked
sasajuric
This is not how I defined it, the typespec is your own addition ![]()
You are
The error message states that ignore return type of the specification is not the subtype of the expected return type for the callback of the application behaviour.
Wher does ignore come from? It’s a part of Supervisor.on_start type.
The Application.start spec in contrast states that valid return values are {:ok, pid()} | {:ok, pid(), state()} | {:error, reason :: term()} (notice the lack of :ignore).
So basically the typespec you provided for Todo.Application.start is incorrect. You could use something like @spec start(Application.start_type, term) :: {:ok, pid} instead.
Fl4m3Ph03n1x
On a personal level, the main reason I recommend your book to people around me in work (besides liking it obviously) is the fact I you are so active in this community.
If one of my co workers has a question about your book that I can’t answer, they can always ask the creator for help. And that is priceless.
sasajuric
Happy to hear that!
I think what’s even more important is that we have a nice community here, so different people can chime in with different points of view, like e.g. @LostKobrakai did earlier in this thread by spotting the difference between Application.start and the start callback. This is why I usually advise people to ask their questions on this forum.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #javascript
- #code-sync
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









