-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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 the error reporting in meson #12154
base: master
Are you sure you want to change the base?
Improve the error reporting in meson #12154
Conversation
Better error reporting is always great. Played a bit with wrong statements in
|
Of course yes, as of now this is just a PoC, I'd like to improve where the error marker lands also so that it's easier to track with the eyes, and improve the line reporting since every node would need to include that, which is a bit ugly as-is. Thanks a lot for some additional checks! That's very interesting given we'll typically need to unwind back in the evaluation for the fs.copyfile back to improve the reporting. Would you like to improve the errors after this message yourself or should I include that in the MR? |
I like this idea. Developers love when tooling is very explicit and makes their live easier, which this does. Thanks for taking this on. FYI you can mark PRs as drafts too. I recently started learning Typst, and the compiler is amazing with errors. |
9246fe4
to
41b1b0a
Compare
mesonbuild/utils/core.py
Outdated
|
||
@classmethod | ||
def from_node(cls, *args: object, node: BaseNode) -> MesonException: | ||
def from_node(cls, *args: object, node: BaseNode, error_resolve: str = None) -> MesonException: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a T.Optional[str]
raise InvalidCode.from_node( | ||
f'Assignment are returning void and not valid in if clause.', | ||
node=i.condition, | ||
error_resolve=f'Did you forget a = here?') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a better message would be "Should this be an equality check?"
mesonbuild/mlog.py
Outdated
@@ -407,8 +409,13 @@ def exception(self, e: Exception, prefix: T.Optional[AnsiDecorator] = None) -> N | |||
node_resolve.append(empty_lineno + ' | ' + e.colno * ' ') | |||
node_resolve.append(yellow(f'{e.error_resolve}')) | |||
|
|||
if getattr(e, 'end_lineno', None) is not None and e.lineno != e.end_lineno: | |||
node_after += [[ ' ...located before...']] | |||
node_after += [ [f' {str(i + e.lineno + 1).rjust(lineno_size)} | ' + line] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the space around the brackets like in [ [
.
mesonbuild/mlog.py
Outdated
with self.force_logging(): | ||
for args_list in [args, node_content, node_marker, node_resolve]: | ||
for args_list in [args, node_content, node_marker, node_resolve] + node_after: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of a +
, add node_after to the array with node_resolve, *node_after]
41b1b0a
to
af9ab7a
Compare
All the linting jobs are failing |
af9ab7a
to
805a19f
Compare
727b118
to
208aba0
Compare
I've addressed the issues from the two linters, but there are still issues with mypy, mostly because of kwargs. I've made the necessary changes to make it work on recent python, but I'm not sure of what should be done. The remaining issues are because the needed type annotations are not available:
Should I try to get rid of the necessity for |
208aba0
to
f65b66e
Compare
cc @dcbaker |
f65b66e
to
b94210d
Compare
For now, I've switched the I've also fixed the lint errors, and changed the error reporting for void function inside if conditions so that it works with every void function, but now they will be evaluated before. (Unfortunately, I don't have any other solution to get the type for now). I have a few changes on commit message to make and the mlog patches to re-improve, and an issue with the project with assignment where the carets are not displayed correctly, and this should be good to go. |
b94210d
to
f797e8a
Compare
f797e8a
to
f8f2beb
Compare
f8f2beb
to
5000436
Compare
95e057b
to
8a53bb0
Compare
Test failures. |
Unfortunately, I'm not sure to understand the remaining errors: CI:
Local:
Is it really related to my changes? |
The current error reporting in meson is very poor and only offers the line where the error happened. For instance, with the following code: if host_system = 'android' Then we get the following confusing error: meson.build:6:17: ERROR: Cannot perform 'if' operation on void statement. This commit adds more information inside the MesonException that will be forwarded from the parser and interpreter to also report the line where the error happened, and a potential solution for resolving the error to the meson user. It also adds typing for the internal variables from the MesonException class.
As highlighted from previous commit, the current error reporting in meson has many cases where it will not really help the user find where the error is. In particular, assignment are void expression and in the case where we forget an equal since in a conditional like the follwoing code: if host_system = 'android' Then we only get the following confusing error: meson.build:6:17: ERROR: Cannot perform 'if' operation on void statement. This commit separate this case to more easily notify the user of where the error really happened, and how to solve it. After this commit, the error will now look like: meson.build:6:3: ERROR: Assignment are returning void and not valid in if clause. meson.build:6:3: | if host_system = 'android' meson.build:6:3: | ^^^^^^^^^^^^^^ meson.build:6:3: | Did you forget a = here?
Longer source reference will be expanded below the diagnostic message: meson.build:6:3: ERROR: message(...) returns void and is not valid in condition. meson.build:6:3: 6 | if message('''foo meson.build:6:3: | ^^^^^^^^^^^^^^ meson.build:6:3: | Move the call to message before the condition meson.build:6:3: ...located before... meson.build:6:3: 7 | bar meson.build:6:3: 8 | baz''') There can be errors with lineno > len(line) + 1. See test in test cases/failing/121 missing compiler/.
In a code with: if message(...): The following error was reported: meson.build:6:3: ERROR: Cannot perform 'if' operation on void statement. Now it will be reported as: meson.build:6:3: ERROR: message(...) returns void and is not valid in condition. meson.build:6:3: 6 | if message('''foo meson.build:6:3: | ^^^^^^^^^^^^^^ meson.build:6:3: | Move the call to message(...) before the condition meson.build:6:3: ...located before... meson.build:6:3: 7 | bar meson.build:6:3: 8 | baz''')
MesonException is the first base class which can store sources, lineno, and other AST information to report the error correctly. This removes the need to disable the type checker on the assignments. The Exception type is still kept but is directly thrown without adding additional information.
fb4ac13
to
9a67adf
Compare
Setting end_colno will allow to correctly indicate the range of any error involving the node. Since any return/whitespace would break the token into another one, it's safe to assume everything is on a single line, and thus bytespan can be used to directly infer the length in bytes and use this value to compute the end_colno value.
This reverts commit 554be659e7f362ca237b64ce507d039b28d6b28a.
This reverts commit 6be0f9fe1ad88e3748b286432ec7609b268e505c.
Even though the current code uses correct lineno/colno, .from_node() has the benefit of forwarding more information (including end_lineno and end_colno) that might benefit future error reporting even more.
Even though the current code uses correct lineno/colno, .from_node() has the benefit of forwarding more information (including end_lineno and end_colno) that might benefit future error reporting even more.
This reverts commit 9a714659ff4abe18a323156fcb7a2534e6c3f556.
Fail after mparser: add resolver string for UTF-8 with BOM case Now, the meson setup will fail (as expected) with the following error message: meson.build:1:0: ERROR: Builder file must be encoded in UTF-8 (with no BOM) meson.build:1:0: 1 | project('utf8 with bom') meson.build:1:0: | ^ meson.build:1:0: | Remove the (invisible) startup BOM character [2] WIP: remove text=
Fail after mparser: add resolver string for UTF-8 with BOM case Now, the meson setup will fail (as expected) with the following error message: meson.build:1:0: ERROR: Builder file must be encoded in UTF-8 (with no BOM) meson.build:1:0: 1 | project('utf8 with bom') meson.build:1:0: | ^ meson.build:1:0: | Remove the (invisible) startup BOM character [2] WIP: remove text=
Fail after mparser: exception trigger source and filename addition
9a67adf
to
81e23cb
Compare
Looks like tests are still failing. A cleaned up git history would also be appreciated! |
Indeed, I've pushed to synchronize between my two machines but the MR is back to not being 100% ready. I've added error handling in mparser.py in this MR because of test that were now failing (from the Failing/ directory, but still failing because they were not matching the expected output). It led to a few fixes on the original MR though, which is nice. I've also changed the behaviour of the caret addition to default to one caret, as it hugely simplify when only a single caret needs to be added and avoid underlining the whole line if the end column is not yet specified. I'm still working on the intermediate patches so that it doesn't break the code in the middle of the branch. Thanks for checking the MR! I'll post again when this is finished. |
Hi,
This MR is in a RFC state for now, many things need to be improved before merging,but I'd like to have feedback on how the error is improved and how to handle the line reporting itself before.This MR stems from a very simple case where I found the error reporting very confusing with the following code:
When running meson, we would only get the following confusing error:
This MR thrive to add the necessary infrastructure and convention to report better errors with a way to solve the issue. Typically, the previous example would now output the following error:
The current implementation is conservative to where the errors were not extended to this new information.
Many questions are arising from that regarding the formatting:
I also implemented the line reporting in an ugly way, by storing the relevant line in every (well for now, only IfClauseNode and AssignmentNode, but that's one of the hypothesis of the code) AST node, but some nodes are spanning on multiple lines and there can be multiple nodes per line, so it looks a bit ugly even though we can make python use a single string in the back. We can also only report the relevant part of the code by referencing
self.code[]
or referencing the relevant substring whenraise
is happening. What would you prefer?