Skip to content

[core] Abort on semantic errors#3892

Merged
oowekyala merged 19 commits into
pmd:pmd/7.0.xfrom
oowekyala:abort-on-semantic-errors
Jun 25, 2022
Merged

[core] Abort on semantic errors#3892
oowekyala merged 19 commits into
pmd:pmd/7.0.xfrom
oowekyala:abort-on-semantic-errors

Conversation

@oowekyala

@oowekyala oowekyala commented Apr 1, 2022

Copy link
Copy Markdown
Member

Describe the PR

This makes us skip rules if semantic errors are reported. This is useful for better error reporting. Previously errors might have been reported by throwing an exception. This hides further errors, now we can also collect them. This makes #3891 more useful.

Related issues

Ready?

  • Added unit tests for fixed bug/feature
  • Passing all unit tests
  • Complete build ./mvnw clean verify passes (checked automatically by github actions)
  • Added (in-code) documentation (if needed)

@oowekyala oowekyala added this to the 7.0.0 milestone Apr 1, 2022
@ghost

ghost commented Apr 1, 2022

Copy link
Copy Markdown
2 Messages
📖 Compared to pmd/7.0.x:
This changeset changes 27 violations,
introduces 18 new violations, 0 new errors and 0 new configuration errors,
removes 25 violations, 0 errors and 0 configuration errors.
Full report
📖 Compared to master:
This changeset changes 57096 violations,
introduces 34418 new violations, 2 new errors and 0 new configuration errors,
removes 138132 violations, 25 errors and 6 configuration errors.
Full report

Generated by 🚫 Danger

@oowekyala oowekyala force-pushed the abort-on-semantic-errors branch from f683215 to 4fa7db2 Compare April 1, 2022 23:44
This should be done more thoroughly in a future PR
@oowekyala oowekyala mentioned this pull request Apr 14, 2022
7 tasks
@oowekyala oowekyala marked this pull request as ready for review April 22, 2022 17:29
@oowekyala oowekyala mentioned this pull request Apr 23, 2022
5 tasks
@adangel adangel self-requested a review April 28, 2022 15:13
Comment thread pmd-core/src/main/java/net/sourceforge/pmd/processor/PmdRunnable.java Outdated
@adangel

adangel commented May 5, 2022

Copy link
Copy Markdown
Member

Hm... there seems to be a general problem now - as the pmd regression tester says at the end:

[main] ERROR net.sourceforge.pmd.PMD - An error occurred while executing PMD.

There are also many reporting of unresolved method calls and such - I guess these are the new reported semantic errors?

E.g.

Unresolved at In: /home/runner/work/pmd/target/repositories/spring-framework/spring-websocket/src/test/java/org/springframework/web/socket/messaging/OrderedMessageSendingIntegrationTests.java:197:3	[MethodCall:197:3]assertThat(messageHandler.getSavedException()).hasMessage(\n\t\t\t\t\"Buffer size \" + 3 

The last line of the progress report seems to be:

Processing files 100% [=] 7551/7551 (0:09:27 / 0:00:00) Violations:307292, Error

Hm... should be something like Errors: xyz - the number of processing errors.

We should solve this before merging these PRs...

@adangel

adangel commented May 5, 2022

Copy link
Copy Markdown
Member

Ok, so the message "[main] ERROR net.sourceforge.pmd.PMD - An error occurred while executing PMD." means: one processing error occurred. So, nothing out of the ordinary.

But - PMD 7 meanwhile exits with failing exit code, if that happens:

stats = PMD.runAndReturnStats(pmd);
if (pmdReporter.numErrors() > 0) {
// processing errors are ignored
return StatusCode.ERROR;
} else if (stats.getNumViolations() > 0 && configuration.isFailOnViolation()) {
return StatusCode.VIOLATIONS_FOUND;
} else {
return StatusCode.OK;
}

I guess, we should restore what the comment (still) says: "// processing errors are ignored".
Or do we have a command line option to enable/disable failing on processing errors?

What I don't understand is, why this happens only on this branch - the baseline on pmd/7.0.x seems to be created without problems - although we find processing errors.

See also #2827 - handling of processing errors with respect to the exit code is still undefined

@adangel

adangel commented May 5, 2022

Copy link
Copy Markdown
Member

Slowly I begin to understand: in the above snippet, we don't check stats.getNumErrors() (which are the processing errors), but we check pmdReport.numError(), which are any errors that are logged with log level errors...

@adangel

adangel commented May 5, 2022

Copy link
Copy Markdown
Member

Ok, it seems to be this error message, that is counted now and changes the exit code:

2022-04-23T18:59:00.3846552Z [main] ERROR net.sourceforge.pmd.PMD - at /home/runner/work/pmd/target/repositories/spring-framework/spring-oxm/build/generated/sources/xjc/java/test/org/springframework/oxm/jaxb/test/package-info.java :1:116: Error during type resolution of node FieldAccess

Note: I can reproduce this message on branch pmd/7.0.x as well, but the exit code is 0 there...

Comment on lines +132 to +137
SemanticErrorReporter reporter = SemanticErrorReporter.reportToLogger(configuration.getReporter(), LOG);
ParserTask task = new ParserTask(
languageVersion,
filename,
sourceCode,
SemanticErrorReporter.reportToLogger(LOG),
reporter,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ok, this is the change: previously we used a new SemanticErrorReporter, now the logs are forwarded to the main message reporter as well, which makes PMD exit with 1 if there are errors logged...

@oowekyala

Copy link
Copy Markdown
Member Author

I'm surprised there is a FieldAccess in a package-info.java

Note: I can reproduce this message on branch pmd/7.0.x as well, but the exit code is 0 there...

That's because semantic errors were previously only forwarded to an slf4j logger, but this PR also forwards them to the MessageReporter, which increments its error count. I thought this was the correct behaviour, but maybe the SemanticErrorReporter should instead create a ProcessingError. I think there is a difference between a ProcessingError (PMD crashes on some file) and a semantic error (PMD detects that the file is not well-formed source code) though...

@adangel

adangel commented May 5, 2022

Copy link
Copy Markdown
Member

Ok, I think, that's what we need to do:

  • Adjust pmd-regression-tester to go on regardless of the exit code
  • Make the exit code part of the comparison
  • To help us in analyzing problems, the regression tester should also collect the stdout/stderr and make it available in the report

Overall, I think, it makes sense to exit with 1 if PMD logged something suspiciously erroneous. We can think about later, whether we should distinguish them from "hard disruption" error condition caused by exceptions (which was till now the only reason why we exited with 1). And how they relate to the processing errors, which we collect in the report.

@adangel

adangel commented May 5, 2022

Copy link
Copy Markdown
Member

I think there is a difference between a ProcessingError (PMD crashes on some file) and a semantic error (PMD detects that the file is not well-formed source code) though...

Yes, probably, maybe. Assuming, that the code compiles, that PMD analyzes, all semantic errors probably point out a bug in PMD. But that would be the same for processing errors...

Maybe the difference is just that (at least, how it's implemented atm): processing errors are unexpected errors and semantic errors are detectable error conditions...

@oowekyala

oowekyala commented May 6, 2022

Copy link
Copy Markdown
Member Author

Maybe the difference is just that (at least, how it's implemented atm): processing errors are unexpected errors and semantic errors are detectable error conditions...

A few thoughts about this

Building on the technical definition of fault and failure:

A semantic error currently is basically a gracefully detected fault, which may or may not cause an error/failure later (in rule execution). The failure can be an exception (processing error), or inconsistent behavior of rules (FNs/FPs). Rules might also "just work" by chance (or, the semantic error itself is an FP). By that reasoning, we could probably tolerate more faults and only skip rule analysis when we know rule processing will almost surely fail.

Currently things like ambiguous references are reported as errors, because that's what a Java compiler would do. But we're not a Java compiler, and skipping rule analysis because of an ambiguous reference seems like overkill. We should probably demote those to warnings, and print something like "warning: input file might be invalid, this may cause problems in rules" (and link to a page of doc with details).

About processing errors, I think they are in the report mostly so that users don't think that the file they occured in is fine because it has no violations. If semantic errors skip rule analysis, then the same argument applies to them, and they should probably cause a processing error to be reported.

This makes me wonder if we need semantic errors at all. Throwing exceptions (SemanticException?) would achieve nearly the same thing. One difference is that you can only throw one exception, whereas you can accumulate errors if you don't throw them. But we still need a way to skip rule analysis even if no exception is thrown.

So in summary,

  • current semantic errors could be demoted to warnings, with a link to some doc so that users understand the consequences, what they should do to fix it or where they can report FPs
  • very important errors would be reported with exceptions, which may be either thrown or given to a MessageReporter without throwing. If you throw it would still end up in a MessageReporter when it's caught (PmdRunnable). All of those would cause processing errors to be logged and rule analysis to be skipped. This way we don't have a new error situation for our exit code, only processing errors.

@oowekyala

Copy link
Copy Markdown
Member Author

I'll try to implement those changes over the weekend

@oowekyala oowekyala merged commit 51c890c into pmd:pmd/7.0.x Jun 25, 2022
@oowekyala oowekyala deleted the abort-on-semantic-errors branch June 25, 2022 17:29
@adangel adangel mentioned this pull request Jan 23, 2023
55 tasks
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.

2 participants