Skip to content

Conversation

donat
Copy link
Member

@donat donat commented Nov 21, 2024

Fixes #31376

Reviewing cheatsheet

Before merging the PR, comments starting with

  • ❌ ❓must be fixed
  • 🤔 💅 should be fixed
  • 💭 may be fixed
  • 🎉 celebrate happy things

@donat

This comment has been minimized.

@donat donat changed the title Donat/problems/render problems on cli Use problem information in build failure message Nov 21, 2024
@bot-gradle

This comment has been minimized.

@donat donat force-pushed the donat/problems/render-problems-on-cli branch from 0cdd3e3 to 9613256 Compare November 21, 2024 13:09
* @return nothing, the method throws an exception
* @since 8.12
*/
RuntimeException throwing(Throwable exception, Collection<? extends Problem> problems);
Copy link
Member Author

Choose a reason for hiding this comment

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

I'm going to do the API cleanup separately.

@bot-gradle

This comment has been minimized.

@donat donat force-pushed the donat/problems/render-problems-on-cli branch from 9613256 to 568dfab Compare November 21, 2024 13:30
@donat donat requested a review from hegyibalint November 21, 2024 13:30
@donat donat force-pushed the donat/problems/render-problems-on-cli branch from 568dfab to d15be93 Compare November 21, 2024 13:30
@donat

This comment has been minimized.

@donat donat marked this pull request as ready for review November 21, 2024 13:31
@bot-gradle

This comment has been minimized.

@donat donat requested review from a team as code owners November 21, 2024 13:31
@donat donat requested review from a team and tresat November 21, 2024 13:31
@bot-gradle

This comment has been minimized.

Copy link
Member

@hegyibalint hegyibalint left a comment

Choose a reason for hiding this comment

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

Happy to see this shaping up!
Left some comments, PTAL.

* @since 8.10
*/
Collection<Problem> getProblems();
public interface ProblemLookup {
Copy link
Member

Choose a reason for hiding this comment

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

🤔 Something doesn't click with me with this classname, but I cannot come up with something better either.
Any case, this is internal so if we come up with something better, we can change it anytime.

Copy link
Member

Choose a reason for hiding this comment

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

ProblemLocator?

Copy link
Member

Choose a reason for hiding this comment

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

🎉 Nice cleanup, happy to see that exception mapping go away (at least from here)

@donat
Copy link
Member Author

donat commented Nov 21, 2024

@hegyibalint Thanks for the review, I'll clean up the items. Some of the issues come from cherry-picking changes from another (wip) branch.

@donat donat requested a review from hegyibalint November 21, 2024 14:37
@donat

This comment has been minimized.

@bot-gradle

This comment has been minimized.

Copy link
Member

@hegyibalint hegyibalint left a comment

Choose a reason for hiding this comment

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

Thanks for the fixes, let's merge this!

@bot-gradle
Copy link
Collaborator

The following builds have failed:

@donat
Copy link
Member Author

donat commented Nov 22, 2024

@bot-gradle merge

@bot-gradle bot-gradle added this pull request to the merge queue Nov 22, 2024
@bot-gradle bot-gradle added this to the 8.12 RC1 milestone Nov 22, 2024
@bot-gradle
Copy link
Collaborator

WARN: Based on labels, this pull request addresses notable issue but no changes to release note found.

Merged via the queue into master with commit bc745fa Nov 22, 2024
33 of 35 checks passed
@bot-gradle bot-gradle deleted the donat/problems/render-problems-on-cli branch November 22, 2024 07:44
}
}
} catch (RuntimeException e) {
e.printStackTrace();
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 should use e.printStackTrace() in our code base. Not sure if you want to do some debug logging here or what is the actual problem we guard against. I'd just throw the runtime exception if we don't have anything in particular to guard against here.

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree, the printStackTrace() call should be deleted. I'd rather not rethrow the exception. We compare exception instances with user-supplied types that can have exotic problems that we don't anticipate. If the comparison fails, I'd not break the control flow but continue with returning null.

Copy link
Member

Choose a reason for hiding this comment

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

How can we find out that the exotic problems (or any problems) happen? Should we print out the problem on the info log?

StackTraceElement[] s1 = t1.getStackTrace();
StackTraceElement[] s2 = t2.getStackTrace();
for (int i = 0; i < s1.length && i < s2.length; i++) {
if (!isSackTraceElementEquals(s1[i], s2[i])) {
Copy link
Member

Choose a reason for hiding this comment

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

isStackTraceElementEquals instead of isSackTraceElementEquals?

return null;
}

private boolean deepEquals(Throwable t1, Throwable t2, List<Throwable> seen) {
Copy link
Member

Choose a reason for hiding this comment

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

I am really surprised we don't have that already somewhere.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've spent some time looking around and I haven't found anything in Gradle nor in 3rd party libs (commons-lang, etc.).


private final Multimap<Throwable, Problem> problemsForThrowables = Multimaps.synchronizedMultimap(HashMultimap.<Throwable, Problem>create());

private final Multimap<Throwable, Problem> problemsForThrowables = Multimaps.synchronizedMultimap(MultimapBuilder.linkedHashKeys().linkedHashSetValues().<Throwable, Problem>build());
Copy link
Member

Choose a reason for hiding this comment

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

❓ Is it a performance problem to use a synchronized multimap here? Can we use some kind of concurrent maps instead?

Copy link
Member Author

@donat donat Nov 28, 2024

Choose a reason for hiding this comment

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

I took a look an I think we cannot really improve the situation by using ConcurrentHashMap. We need to ensure that updating the list of values are update atomically, which requires synchronisation anyway.

Copy link
Member

Choose a reason for hiding this comment

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

Updating the list doesn't require synchronization if you use ConcurrentHashMap.compute(). ConcurrentHashMap should take care of that. Or are you referring to another list?

public Map<Throwable, Collection<Problem>> getProblemsForThrowables() {
return problemsForThrowables.asMap();
public ProblemLookup getProblemLookup() {
return new DefaultProblemLookup();
Copy link
Member

Choose a reason for hiding this comment

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

❓ Why do we recreate this expensive class on each call instead of keeping the last one around?

Copy link
Member Author

Choose a reason for hiding this comment

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

It raises concurrency issues if we cache the problem lookup. At the same time, we can make the expensive part (ie. initLookup() lazy).

Comment on lines -82 to +80
public Map<Throwable, Collection<Problem>> getProblemsForThrowables() {
return problemContainer.getProblemsForThrowables();
public ProblemLookup getProblemLookup() {
return problemContainer.getProblemLookup();
Copy link
Member

Choose a reason for hiding this comment

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

🤔 That looks somewhat problematic: The problem lookup is only ready at the end, though we allow the lookup from the details object. Why is the problem lookup not a service?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll probably need some help with that. FWIW problemlookup needs to be accessible ClientForwardingBuildOperationListener which is created in the context of ToolingBuilderServices which has no access to build tree scope services.

public Map<Throwable, Collection<Problem>> getProblemsForThrowables() {
return problemContainer.getProblemsForThrowables();
public ProblemLookup getProblemLookup() {
return problemContainer.getProblemLookup();
Copy link
Member

Choose a reason for hiding this comment

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

💅 problemContainer should probably be called exceptionProblemRegistry.

public interface CompilationFailedIndicator extends NonGradleCause {

@Nullable
String getDiagnosticCounts();
Copy link
Member

Choose a reason for hiding this comment

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

💅 The name of this makes me think it is going to return structured data containing the counts. Maybe reportDiagnosticSummary() or something might be a better name.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for helping out with the naming!

Copy link
Member Author

Choose a reason for hiding this comment

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

getDiagnosticSummary or getReportDiagnosticSummary?

String message = t.getMessage();
result = message == null ? "" : message;
} catch (RuntimeException ignore) {
// ignore exceptions with faulty getMessage() implementation
Copy link
Member

Choose a reason for hiding this comment

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

❓ Won't this cause issues finding the proper exception if there are multiple instances of an exception with a faulty getMessage() implementation that are thrown?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't see how. Both faulty exceptions would have still the same key in the lookup.

* @since 8.10
*/
Collection<Problem> getProblems();
public interface ProblemLookup {
Copy link
Member

Choose a reason for hiding this comment

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

ProblemLocator?


@Override
public String getDiagnosticCounts() {
return null;
Copy link
Member

Choose a reason for hiding this comment

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

💅 Shouldn't this method be annotated @Nullable as well?

@donat
Copy link
Member Author

donat commented Nov 28, 2024

@tresat @wolfs The changes addressing your review items are here: #31450

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.

Builds failing via Problems.throwing() should render problems in the failure output

5 participants