Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Error messages #129

Open
ktec opened this issue Jun 13, 2022 · 0 comments
Open

Improve Error messages #129

ktec opened this issue Jun 13, 2022 · 0 comments

Comments

@ktec
Copy link
Contributor

ktec commented Jun 13, 2022

Currently the error messages look something like this:

iex> AgeCheck.user_older_than?("foobar", 42)
** (TypeCheck.TypeError) At lib/type_check_example.ex:28:
The call to `user_older_than?/2` failed,
because parameter no. 1 does not adhere to the spec `%User{age: integer(), name: binary()}`.
Rather, its value is: `"foobar"`.
Details:
  The call `user_older_than?("foobar", 42)` 
  does not adhere to spec `user_older_than?(%User{age: integer(), name: binary()},  integer()) :: boolean()`. Reason:
    parameter no. 1:
      `"foobar"` does not check against `%User{age: integer(), name: binary()}`. Reason:
        `"foobar"` is not a map.
    (type_check_example 0.1.0) lib/type_check_example.ex:28: AgeCheck.user_older_than?/2

There is considerable duplication here which can be confusing for new users at least. I wonder if we could improve this somehow.

I guess the tasks here are:

  1. Decide on how to reduce the duplication and then improve the default formatter
  2. Define a "consise formatter" which presents the same info with brevity

I'll start the discussion using the example above.

This provides me information about the type mismatch:

iex> AgeCheck.user_older_than?("foobar", 42)
** (TypeCheck.TypeError) At lib/type_check_example.ex:28:
The call to `user_older_than?/2` failed,
because parameter no. 1 does not adhere to the spec `%User{age: integer(), name: binary()}`.
Rather, its value is: `"foobar"`.

This tells me the same thing, with the following additional information:

  • a spec of the function
  • a more complete location of the function (eg. includes the app and module)
  • that "foobar" is not a map
Details:
  The call `user_older_than?("foobar", 42)` 
  does not adhere to spec `user_older_than?(%User{age: integer(), name: binary()},  integer()) :: boolean()`. Reason:
    parameter no. 1:
      `"foobar"` does not check against `%User{age: integer(), name: binary()}`. Reason:
        `"foobar"` is not a map.
    (type_check_example 0.1.0) lib/type_check_example.ex:28: AgeCheck.user_older_than?/2

I don't know the default formatter well enough to suggest what's possible, but perhaps I can suggest something (slightly influenced by elm errors):

iex> AgeCheck.user_older_than?("foobar", 42)
** (TypeCheck.TypeError) At lib/type_check_example.ex:28:
The call to `user_older_than?/2` failed, because the 1st parameter does not adhere to the spec;

    user_older_than?(%User{age: integer(), name: binary()},  integer()) :: boolean()
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You have given the value:

                          "foobar"

But a value of the following type is required:

                          `%User{age: integer(), name: binary()}`

Details:
  reason: "is not a map"
  (type_check_example 0.1.0) lib/type_check_example.ex:28: AgeCheck.user_older_than?/2

I know the "details" section bounces down the types to get to the error, so it might be that this just doesn't work, but maybe this will start the discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant