Skip to content

Conversation

@dkuku
Copy link
Contributor

@dkuku dkuku commented Feb 14, 2025

image
It would be ideal if the exception would contain the left part of the match but just pretty printing it makes much difference.
I'm just not sure what to do with the doctest?

"""
no match of right hand side value:
#{inspect(exception.term, pretty: true, limit: :infinity)}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can pretty print but we should not set it to infinity. Given this goes to production logs, it can have a pretty negative impact.

@dkuku
Copy link
Contributor Author

dkuku commented Feb 15, 2025

Good spot.
I wonder what to do with the failing doctest??
Also should we unify all the match errors: MatchError, CaseClauseError, WithClauseError.
Having the result pretty printed makes it easier to compare what didn't match.

@dkuku
Copy link
Contributor Author

dkuku commented Feb 15, 2025

I did a helper and used it in all places that use term in the message. The protocol error already formats the term with indentation so I just copied the pattern.
Also one of the messages was using infinity, it was removed.

@dkuku dkuku changed the title pretty format badmatch error pretty format terms in errors Feb 15, 2025
_ -> message <> "\n" <> format_stacktrace(stacktrace)
end
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should mark it as @doc false. Preferably underscore it too.

inspected =
term
|> inspect(pretty: true)
|> String.replace(~r/^(?=.+)/m, " ")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to achieve this by splitting on new lines and indenting every non empty string.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add padding option to inspect at some point.

Comment on lines 186 to 188
|> String.split("\n", trim: true)
|> Enum.map(&(" " <> &1))
|> Enum.join("\n")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want to trim, because that will remove empty lines and change what was formatted. You either want to indent all lines, which means a |> String.replace("\n", "\n ") or do:

Suggested change
|> String.split("\n", trim: true)
|> Enum.map(&(" " <> &1))
|> Enum.join("\n")
|> String.split("\n")
|> Enum.map(fn
"" -> ""
line -> " " <> line
end)
|> Enum.join("\n")

* :created_at
* :finished_at
* :started_at
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also an issues:
I think it should be something like:

key :firts not found, did you mean:

    * :first

in:

    [ data: :structure]
...

This is more natural imo - you first check the suggestion and then go to the printed structure.
With the current implementation, you have to go back after reading the suggestion.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not change the order for now but we definitely need to fix the line breaking.

@dkuku
Copy link
Contributor Author

dkuku commented Feb 17, 2025

Ok, so I'm not sure how to handle the failing doctests, the rest is ready I think.

@josevalim
Copy link
Member

Could we use #14210 in here? We may need to kill the doctests though.

@dkuku
Copy link
Contributor Author

dkuku commented Feb 17, 2025

Could we use #14210 in here? We may need to kill the doctests though.

Yes, I knew that I saw it somewhere. It was implemented just in time for this.
Now it's ready for review.

@josevalim josevalim merged commit f1bf1b8 into elixir-lang:main Feb 18, 2025
10 checks passed
@josevalim
Copy link
Member

💚 💙 💜 💛 ❤️

@grzuy
Copy link
Contributor

grzuy commented Oct 9, 2025

Hi there 👋

While testing tower package with upcoming Elixir 1.19, noticed this pull request changed significantly the string format of Exception.message (and in turn Exception.format_banner) output for MatchError, KeyError and many others (those with a term field in the Exception), from a one-liner string to now multi-line (potentially lots of lines) strings.

Haven't yet dug too deep into this, and not saying there's an issue with that, just wanted to share it and double check that was the intention, given that the description in this pull request shows the output of the error in a test case failure only.

So noting that this will also affect of how the exception message and banner is formatted in log output and any other packages that depend on Exception.message or Exception.format_banner, like 3rd party exception reporter packages.

Thanks!

@sabiwara
Copy link
Contributor

sabiwara commented Oct 9, 2025

I personally noticed broken doctests in several packages that I maintain as well, and had to conditionally disable doctests in the CI depending on the version (example). The doctests also look less nice.

I wonder if we could avoid the line breaks for smaller terms, by relying on inspect algebra and fitting rules 💭

@dkuku
Copy link
Contributor Author

dkuku commented Oct 10, 2025

It's a bit about what's better—human readability vs machine readability for tests. Maybe supporting multiline strings in iex somehow would be an option. Or having a way to use =~ in doctests? Most of the error messages generated by compiler now are multiline.

@sabiwara
Copy link
Contributor

sabiwara commented Oct 10, 2025

Or having a way to use =~ in doctests?

We now have it through the use of ellipsis (...), problem is that it's not supported in older versions of Elixir so tests wouldn't pass on these versions yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants