A pitfall of GenServer programming in Elixir

OTP as a programming platform/framework, empowers not only Erlang, but also Elixir. This post looks into a pitfall when programming GenServer in Elixir, and provides a potential solution.

All callbacks in the GenServer behavior have a limited and pre-defined possible return values. Presumbly, one should pick up the desired return value from valid ones. One example for handle_call/3 looks like below:

{:reply, reply, new_state}

But what if we screw the return value, e.g., by mistakes like below,

{:reply, reply, :ok, new_state}

where atom :ok is added as an extra parameter of the return value. One would hope the Elixir compiler would catch this simple mistake. Nevertheless, neither mix compile or mix escript.build would report this bug. And yes, this bug will be triggered when handle_call/3 is called with a “Bad Argument” exception thrown out.

While “let it crash” and “unit testing” may be good reasons for Elixir compiler to treat this bug as a runtime one rather than a compiling one, this also means this simple bug won’t be discovered util deployment if unit testing is not covered properly. And once it happens, it keeps crashing “thanks” to the fault-tolerant feature using Supervisor…

Without changes in the Elixir compiler, it is still possible to detect this bug, using dialyxir (yes, Elixir version of dialyzer for sure). “mix dialyxir” shows the detection of this bug:

done in 0m1.52s
lib/dig.ex:9: The inferred return type of handle_call/3 ({‘reply’,{‘ok’,{_,_,_,_,_}},’ok’,#{‘__struct__’:=’Elixir.Digdb’, ‘node’:=_, ‘prefix’:=_, ‘remote’:=_, ‘unit_base’:=_, ‘unit_range’:=_, ‘worker_idx’:=_, ‘zero_num’:=_}}) has nothing in common with {‘noreply’,_} | {‘noreply’,_,’hibernate’ | ‘infinity’ | non_neg_integer()} | {‘reply’,_,_} | {‘stop’,_,_} | {‘reply’,_,_,’hibernate’ | ‘infinity’ | non_neg_integer()} | {‘stop’,_,_,_}, which is the expected return type for the callback of the ‘Elixir.GenServer’ behaviour
done (warnings were emitted)

About daveti

Interested in kernel hacking, compilers, machine learning and guitars.
This entry was posted in Programming, Static Code Analysis and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.