[erlang-questions] Dialyzer cannot catch gen_server callback return type error

Maxim Treskin <>
Thu Jul 5 13:44:12 CEST 2012


On 5 July 2012 18:17, Motiejus Jakštys <> wrote:

> On Thu, Jul 05, 2012 at 04:12:01PM +0700, Maxim Treskin wrote:
> > Hello
> >
> > I got error when gen_server callback returns not a proper process state,
> > but another erlang term(), and dialyzer not warns me about this.
> > After specification of Module:handle_cast/2 with
> >
> > -spec handle_cast(Msg :: term(), State :: #state{}) -> {noreply, NewState
> > :: #state{}}.
> >
> > where #state{} is record of process state,
>
> I don't know about this one,
>
> > it not warns too (it also not warns about {stop, normal, State} return
> > value).
>
> but this is fine. Your function returns a *subtype* of what
> Mod:handle_cast/2 is supposed to return.
>
> No, handle_cast really returns {stop, normal, State}, but this return type
not described in -spec of handle_cast, function returns not a subtype of
declared type. Dialyzer is silent.


> If you added something that is not in return values of handle_cast, like
> this:
>
> -spec handle_cast(term(), #state{}) -> {noreply, NewState} | wrong.
>
> Dialyzer will warn you that gen_server is not expecting 'wrong'.
>

Yes, I see such warning:

my_module.erl:215: The return type 'wrong' in the specification of
handle_cast/2 is not a subtype of {'noreply',_} | {'noreply',_,'hibernate'
| 'infinity' | non_neg_integer()} | {'stop',_,_}, which is the expected
return type for the callback of gen_server behaviour
my_module.erl:215: The specification for my_module:handle_cast/2 states
that the function might also return 'wrong' but the inferred return is
{'noreply',_} | {'stop',{'error',{_,_}},{'state',_}}

It seems dialyzer uses less strict declaration of callback from behaviour
-callback specification. I think it should be more appreciated to overlap
-callback specification from behavior with -spec in callback module. When
my_module.erl not contains -spec handle_cast(...) -> ..., dialyzer should
use type description from gen_server.erl -callback declaration, but if we
want to restrict this type in my_module.erl with -spec declaration this
value should be used.



>
> > Code of callback:
> >
> > handle_cast({message}, _State) ->
> >     NewState = {bugotak},
> >     {noreply, NewState};
> >
> > Is it possible to make that dialyzer can see this mistake? Does it check
> > types of gen_server callbacks?
>
> But this one would be interesting indeed.
>
> Motiejus
>



-- 
Max Treskin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20120705/e40b0b44/attachment.html>


More information about the erlang-questions mailing list