[erlang-questions] Typespecs of functions that may fail

Kostis Sagonas kostis@REDACTED
Tue Jan 17 16:52:12 CET 2017


On 01/17/2017 03:47 PM, Bastien Chamagne wrote:
> Hello,
>
> I'm trying to use dialyzer and I don't know how to type functions that
> are written in "happy path" (may crash).

Dialyzer's core (known as "success typings") are designed for _exactly_ 
this purpose.  So that you only specify what's happening in the "happy 
paths", i.e., in the paths that a function returns ("succeeds").  So you 
cannot (and should not) specify anything regarding the "sad paths."


> Here's a sample function that may or may not crash depending if Field
> correspond to a relation field on given Model:
>
>     -spec is_relation(field(), model()) -> {true, relation_type()} | false.
>
>     %% @doc Sets a relation on the given model.
>     -spec set_relation(field(), model(), model()) -> model() | no_return().
>     set_relation(Field, RelatedModel, Model) ->
>         % On next line, I'm OK that this function crashes if I try to
> set a relation on a non-relation field
>         {true, RelationType} = is_relation(Field, Model),
>         set_relation(Field, RelatedModel, Model, RelationType).
>
> Here's what dialyzer says:
>
>     model.erl:180: Function set_relation/3 has no local return
>     model.erl:181: The pattern {'true', RelationType} can never match
> the type 'false'
>
> Is there anything that I can do to inform dialyzer that this is a OK
> behaviour for me?

This behaviour should NOT be OK for you.  Dialyzer is telling you that 
it has somehow discovered that it your is_relation/2 function call 
always returns 'false' here.  Unless your version of Dialyzer has some 
bug, which is unlikely, you cannot ignore that this warning.

In any case, the problem is not in the set_relation/2 function but in 
the is_relation/2 function for which you have not showed us its code; 
actually, you need to show us the whole module in order to tell you with 
certaintly what's happening.


Kostis

PS. Types of the form  type() | no_return()  are equally verbose as 
writing 42 + 0 for the integer 42 ...



More information about the erlang-questions mailing list