Skip to content

Commit

Permalink
Improve error message in case resolve fails
Browse files Browse the repository at this point in the history
Currently Tycho gives a rather vague message ('see log for details') if
a resolve fails for a project what requires the user to search and match
the actual error if the resolving of a project fails.

This now adds the errors directly to the exception what gives a much
better info to the user in case of resolve failure.
  • Loading branch information
laeubi committed Jan 19, 2024
1 parent 253632e commit 36596d6
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@
import org.eclipse.tycho.ArtifactDescriptor;
import org.eclipse.tycho.ArtifactKey;
import org.eclipse.tycho.DependencyArtifacts;
import org.eclipse.tycho.DependencyResolutionException;
import org.eclipse.tycho.ReactorProject;
import org.eclipse.tycho.core.TargetPlatformConfiguration;
import org.eclipse.tycho.core.TychoProject;
import org.eclipse.tycho.core.TychoProjectManager;
import org.eclipse.tycho.core.osgitools.DefaultArtifactDescriptor;
import org.eclipse.tycho.core.osgitools.DefaultReactorProject;
import org.eclipse.tycho.p2.resolver.ResolverException;
import org.eclipse.tycho.p2maven.DependencyChain;
import org.eclipse.tycho.p2maven.InstallableUnitGenerator;
import org.eclipse.tycho.resolver.TychoResolver;
Expand Down Expand Up @@ -105,7 +107,22 @@ public void beforeProjectLifecycleExecution(ProjectExecutionEvent event) throws
try {
legacySupport.setSession(mavenSession);
//FIXME should return tycho project!
resolver.resolveProject(mavenSession, mavenProject);
try {
resolver.resolveProject(mavenSession, mavenProject);
} catch (DependencyResolutionException e) {
ResolverException resolverException = findResolverException(e);
if (resolverException == null) {
throw new LifecycleExecutionException(
"Cannot resolve dependencies of project " + mavenProject.getId(), null, mavenProject, e);
} else {
throw new LifecycleExecutionException(
"Cannot resolve dependencies of project " + mavenProject.getId() + System.lineSeparator()
+ " with context " + resolverException.getSelectionContext()
+ System.lineSeparator() + resolverException.explanations()
.map(exp -> " " + exp.toString()).collect(Collectors.joining("\n")),
null, mavenProject);
}
}
TychoProject tychoProject = projectManager.getTychoProject(mavenProject).orElse(null);
if (tychoProject != null) {
try {
Expand All @@ -131,6 +148,21 @@ public void beforeProjectLifecycleExecution(ProjectExecutionEvent event) throws
}
}

private ResolverException findResolverException(Throwable t) {
if (t != null) {
if (t instanceof ResolverException re) {
return re;
}
for (Throwable sup : t.getSuppressed()) {
if (sup instanceof ResolverException re) {
return re;
}
}
return findResolverException(t.getCause());
}
return null;
}

private Set<MavenProject> checkBuildState(TychoProject tychoProject, MavenProject project) throws CoreException {
ReactorProject reactorProject = DefaultReactorProject.adapt(project);
DependencyArtifacts artifacts = tychoProject.getDependencyArtifacts(reactorProject);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@
*******************************************************************************/
package org.eclipse.tycho.p2.resolver;

import java.util.Collection;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.equinox.internal.p2.director.Explanation;
import org.eclipse.tycho.core.shared.StatusTool;

/**
Expand All @@ -25,13 +30,19 @@ public class ResolverException extends Exception {
private static final long serialVersionUID = 1L;
private final String details;
private final String selectionContext;
private Collection<Explanation> explanation;

public ResolverException(String msg, Throwable cause) {
super(msg, cause);
selectionContext = "N/A";
details = "N/A";
}

public ResolverException(Collection<Explanation> explanation, String selectionContext, Throwable cause) {
this(explanation.stream().map(Object::toString).collect(Collectors.joining("\n")), selectionContext, cause);
this.explanation = explanation;
}

public ResolverException(String details, String selectionContext, Throwable cause) {
super("See log for details", cause);
this.details = details;
Expand All @@ -52,4 +63,8 @@ public String getSelectionContext() {
return selectionContext;
}

public Stream<Explanation> explanations() {
return explanation.stream();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ public Collection<IInstallableUnit> resolve(Map<String, String> properties, IPro
// log all transitive requirements which cannot be satisfied; this doesn't print the dependency chain from the seed to the units with missing requirements, so this is less useful than the "explanation"
logger.debug(StatusTool.toLogMessage(s));
explainProblems(explanation, MavenLogger::error);
throw new ResolverException(explanation.stream().map(Object::toString).collect(Collectors.joining("\n")),
selectionContext.toString(), StatusTool.findException(s));
throw new ResolverException(explanation, selectionContext.toString(), StatusTool.findException(s));
}
if (s.getSeverity() == IStatus.WARNING) {
logger.warn(StatusTool.toLogMessage(s));
Expand Down

0 comments on commit 36596d6

Please sign in to comment.