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

JSON errors parsing enhancement #62

Merged
merged 8 commits into from
Sep 19, 2016
Merged

JSON errors parsing enhancement #62

merged 8 commits into from
Sep 19, 2016

Conversation

alygin
Copy link
Collaborator

@alygin alygin commented Sep 17, 2016

I've improved support for JSON error format and made it default.

  1. All spans are now parsed and added to trace. No missing information anymore.
  2. Label of the primary span is added to the main message. For instance, before: "mismatched types", after: "mismatched types (expected u32, found i32)".
  3. Error code is added to the main message when possible. Before: "field a bound multiple times in the pattern", after: "field a bound multiple times in the pattern [E0027]".
  4. For an errors within a macro, the macro definition is added to the trace. A special message type Macro is created for that.
  5. A list of redundant messages is created to prevent displaying span labels that repeat the main message text in different wording. For instance, it's "struct Foo does not have a field named bar" instead of "struct Foo does not have a field named bar (struct Foo does not have field bar)". The list is safe to use because it checks exact message templates, so no useful information will be removed even if the error messages will be changed in the future. List is filled with three dozens of such messages, but can be easily expanded when redundancy is noticed.
  6. If a trace item has the same location as the main message, this location is omitted in such an item to remove unnecessary noise.
  7. A special case messages can be handled now before displaying. For instance, the compiler doesn't emit location for the error "main function not found". I add "src/main.rs" to such messages. It's not the ideal solution, but works better than what we have now.
  8. Parsers (for JSON messages and for panics) are moved to their own files to simplify further maintenance.
  9. JSON output format is default now.

I've checked it on several dozens of error messages and found no problems with missing useful information from the original JSON message. If you notice something, please, let me know.

I left the standard output parsing intact, just made a simple fix to prevent it from displaying broken messages when the new error format is used. So, it now works for the current error format but is effectively switched off for the new error format (I've provided a caveat in the "JSON format" setting description).

I'm intended to get back to the new error format parsing shortly. But it will be a separate PR.

There's an issue to discuss: what should we do with the existing settings? Should we forcefully switch all the users to the JSON format while upgrading? Since the standard output has been default so far, many use it and might lose linter messages after switching to the new error format if we do nothing. I'm not sure I'll have time to implement new parser quickly (after a closer look, I'm not even sure that it might be properly implemented for all errors).

Fixes #61

return true;
}
if (msg.message === 'main function not found') {
msg.file = buildWorkDir + '/src/main.rs'; // TODO: When running an example, set the path to the example file.
Copy link
Contributor

Choose a reason for hiding this comment

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

that path can be changed in Cargo.toml ... why not file it as a rustc bug, that the file is not reported in the json error represntation instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I tried pointing it to Cargo.toml but then switched back because it's very unlikely that Cargo.toml is the file in which the developer will be fixing this problem. It's usually either src/main.rs or one of the examples. Making difference between main.rs and an example file requires passing a wider building context to this function. Since we don't do it now, I just left main.rs.

I'm not sure what solution is better. Cargo.toml is universal, but seems useless from the practical point of view.

Regarding filing a bug, I'm going to do that after studying it a bit closer to be able to come up with some practical suggestions. I told Jonathan about it but to no avail so far.

Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest not to guess the filename in atom, if it is not specified. Instead you could display all errors with missing filenames as error pop-ups, as you did with the runtime errors.

Ultimately this should be fixed in rustc instead.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't like guessing filenames either, but we only use it for a particular message for which it's really possible to guess the exact file. There's another exceptional error message: error: aborting due to previous error that is simply ignored now because it doesn't relate to the source code.

I would suggest the following:

  1. Ignore the aborting due to previous error error.
  2. Keep a special case for the main function not found error (provide the filename ourselves) until it's fixed in Rust (here's the issue).
  3. Display notifications for all other messages with no location in case we encounter something unknown at this time.

Copy link
Contributor

Choose a reason for hiding this comment

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

The thing is that the path can be customised, with the following Cargo.toml it is src/foo.rs and not src/main.rs.

[[bin]] name = "foo" path = "src/foo.rs"

You can completely overwrite this behaviour and even define multiple binaries. In these edge cases the guess will be wrong and point to a nonexistent or not the right file. Pointing to the wrong binary might be especially confusing if that one has a main function...

The question is, is it worth to have better diagnostics in 97℅ of the cases if that means getting 3℅ completely wrong? These numbers are just my personal estimate and may be far off.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

You're right. Given such configuration possibilities, it's better not to divine. I'll remove this special case and add notifications.

@colin-kiegel
Copy link
Contributor

I think there is good reason to change the setting to json for everyone after the update

@alygin
Copy link
Collaborator Author

alygin commented Sep 18, 2016

Errors without locations are displayed as notifications now.
The "JSON error format" setting will be set to true for all users after the upgrade.

Copy link
Contributor

@oli-obk oli-obk left a comment

Choose a reason for hiding this comment

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

Just some nits. This is great work!

We should probably start bugging rustc devs to add a compiler option to generate json-producing panic code.

&& span.column_end === msg.col_end;
}

// Appends spans's lable to the main message. It only adds the lable if:
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: label

if (!span.label || msg.message.indexOf(span.label) >= 0) {
return;
}
for (let idx = 0; idx < redundantLabels.length; idx++) {
Copy link
Contributor

Choose a reason for hiding this comment

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

for (var l in redundantLabels)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In JS, for (var l in redundantLabels) iterates through indices, not through the array elements. At first glance, it looked counterintuitive to me, so I decided to leave the explicit iteration through indices.

redundantLabels.forEach() also doesn't work well here because it becomes too wordy when you need to return from the main function within a forEach-callback.

Copy link
Contributor

Choose a reason for hiding this comment

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

oh... that's very confusing. redundandLabels.some() is too unreadable, so lets stay with this.

'use babel';

//
// Panics and stack backtrades parser.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: backtraces

// - the main message doesn't contain exactly the same phrase
// - the main message doesn't contain the same information but uses different wording
function appendSpanLabel(span, msg) {
if (!span.label || msg.message.indexOf(span.label) >= 0) {
return;
}
for (let idx = 0; idx < redundantLabels.length; idx++) {
for (idx in redundantLabels) {
Copy link
Contributor

Choose a reason for hiding this comment

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

missing var

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's not only var, Travis requires an additional if within the loop because it thinks that I iterate through the simple object properties and must check if those properties are internal or not. With such check the loop becomes more wordy. It seems the original loop was more concise than any other option.

@oli-obk oli-obk merged commit d79fd62 into AtomBuild:master Sep 19, 2016
@alygin alygin deleted the json-parsing-enhancement branch September 20, 2016 14:10
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

Successfully merging this pull request may close these issues.

update to new Rust error format and/or move to json solely
3 participants