Gracefully handle bad user input #467
-
I feel like I hit this the last time I tried Gradualizer but can't remember if I brought it up anywhere, sorry if I have already brought this up :) In OpenTelemetry we try to handle bad user input by not crashing. So we end up with code like this https://github.com/open-telemetry/opentelemetry-erlang/blob/main/apps/opentelemetry_api/src/opentelemetry.erl#L386 -type status() :: #status{}.
-type status_code() :: ?OTEL_STATUS_UNSET | ?OTEL_STATUS_OK | ?OTEL_STATUS_ERROR.
-spec status(Code) -> status() | undefined when
Code :: status_code().
status(Code) ->
status(Code, <<>>).
-spec status(Code, Message) -> status() | undefined when
Code :: status_code(),
Message :: unicode:unicode_binary().
status(?OTEL_STATUS_ERROR, Message) when is_binary(Message) ->
#status{code=?OTEL_STATUS_ERROR, message=Message};
status(?OTEL_STATUS_OK, _Message) ->
#status{code=?OTEL_STATUS_OK};
status(?OTEL_STATUS_UNSET, _Message) ->
#status{code=?OTEL_STATUS_UNSET};
status(_, _) ->
undefined. Gradualizer, rightly, tells me that it is not possible to return
In the few minutes of usage Gradualizer has shown to be very useful in finding mistakes dialyzer can't, so I'd really like to consistently be able to use it going forward, but there is too much noise caused by how we need to ignore bad input. Unless it is already possible and I simply missed it, does it sound feasible to ignore individual functions, isntead of individual modules, like we do with dialyzer in rebar3:
I might be able to find time to add that to Gradualizer's rebar3 plugin if so. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 7 replies
-
What version of Gradualizer are you running? The error that you get looks like a bug. Gradualizer doesn't recognize that |
Beta Was this translation helpful? Give feedback.
-
I understood this differently. I thought you got an error saying that the last clause This is what we call exhaustiveness checking. We don't have an option to disable exhaustiveness checking but we might consider it. Your use case, code that needs to handle "bad user input", i.e. the caller passing arguments that don't follow the spec, is interesting. You know that the last clause can't be reached if the caller calls it according to the spec, but it can be reached if the caller code contains a type error, but the caller code is not within the same project and might not be type checked. I think this is an interesting discussion. |
Beta Was this translation helpful? Give feedback.
What version of Gradualizer are you running? The error that you get looks like a bug. Gradualizer doesn't recognize that
status()
and#status{}
is the same type.Is it feasible for you to try with the latest revision from github? I believe @erszcz has fixed the bug you're running into.