Repository: mojohaus/versions
Pull request #1224 (2025-03-16 10:54:23)

Exposing the problem causing artifact if Resolver throws an exception
Any problems causing the Resolver to fail resolving a version should be reported to the end user,  including the artifact causing the problem which can facilitate problem resolution on the resolver end. 

Here we're propagating the information about the problematic artifact to the mojo which can then output it in the log.

Related: #1147 

andrzejj0: @slawekjaranowski please check; we can release after this one is merged.

Patch:
diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java b/versions-common/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java
index 5d18238a..c03d6295 100644
--- a/versions-common/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java
+++ b/versions-common/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java
@@ -216,7 +216,11 @@ public class DefaultVersionsHelper implements VersionsHelper {
                             .map(v -> ArtifactVersionService.getArtifactVersion(v.toString()))
                             .collect(Collectors.toList()));
         } catch (VersionRangeResolutionException e) {
-            throw new VersionRetrievalException(e.getMessage(), e);
+            throw new VersionRetrievalException(e.getMessage(), artifact, e);
+        } catch (RuntimeException e) {
+            // log the dependency should any runtime exception occur (e.x. broken comparison contract)
+            throw new VersionRetrievalException(
+                    "Unable to retrieve versions for " + artifact + " for version range " + versionRange, artifact, e);
         }
     }
 
@@ -266,9 +270,12 @@ public class DefaultVersionsHelper implements VersionsHelper {
             }
 
             return dependencyUpdates;
-        } catch (ExecutionException | InterruptedException ie) {
+        } catch (ExecutionException | InterruptedException e) {
+            if (e.getCause() instanceof VersionRetrievalException) {
+                throw (VersionRetrievalException) e.getCause();
+            }
             throw new VersionRetrievalException(
-                    "Unable to acquire metadata for dependencies " + dependencies + ": " + ie.getMessage(), ie);
+                    "Unable to acquire metadata for dependencies " + dependencies + ": " + e.getMessage(), null, e);
         } finally {
             executor.shutdown();
         }
@@ -310,9 +317,12 @@ public class DefaultVersionsHelper implements VersionsHelper {
             }
 
             return pluginUpdates;
-        } catch (ExecutionException | InterruptedException ie) {
+        } catch (ExecutionException | InterruptedException e) {
+            if (e.getCause() instanceof VersionRetrievalException) {
+                throw (VersionRetrievalException) e.getCause();
+            }
             throw new VersionRetrievalException(
-                    "Unable to acquire metadata for plugins " + plugins + ": " + ie.getMessage(), ie);
+                    "Unable to acquire metadata for plugins " + plugins + ": " + e.getMessage(), null, e);
         } finally {
             executor.shutdown();
         }
diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/api/VersionRetrievalException.java b/versions-common/src/main/java/org/codehaus/mojo/versions/api/VersionRetrievalException.java
index 483e57f8..29f4f90b 100644
--- a/versions-common/src/main/java/org/codehaus/mojo/versions/api/VersionRetrievalException.java
+++ b/versions-common/src/main/java/org/codehaus/mojo/versions/api/VersionRetrievalException.java
@@ -19,17 +19,26 @@ package org.codehaus.mojo.versions.api;
  * under the License.
  */
 
+import java.util.Optional;
+
+import org.apache.maven.artifact.Artifact;
+
 /**
  * Exception thrown if version information cannot be retrieved
  */
 public class VersionRetrievalException extends Exception {
+
+    private final Artifact artifact;
+
     /**
      * Constructs a new exception with {@code null} as its detail message.
      * The cause is not initialized, and may subsequently be initialized by a
      * call to {@link #initCause}.
+     *
+     * @param artifact {@link Artifact} instance causing the problem
      */
-    public VersionRetrievalException() {
-        super();
+    public VersionRetrievalException(Artifact artifact) {
+        this(null, artifact);
     }
 
     /**
@@ -37,11 +46,13 @@ public class VersionRetrievalException extends Exception {
      * cause is not initialized, and may subsequently be initialized by
      * a call to {@link #initCause}.
      *
+     * @param artifact {@link Artifact} instance causing the problem
      * @param   message   the detail message. The detail message is saved for
      *          later retrieval by the {@link #getMessage()} method.
      */
-    public VersionRetrievalException(String message) {
+    public VersionRetrievalException(String message, Artifact artifact) {
         super(message);
+        this.artifact = artifact;
     }
 
     /**
@@ -52,13 +63,14 @@ public class VersionRetrievalException extends Exception {
      * wrappers for other throwables (for example, {@link
      * java.security.PrivilegedActionException}).
      *
+     * @param artifact {@link Artifact} instance causing the problem
      * @param  cause the cause (which is saved for later retrieval by the
      *         {@link #getCause()} method).  (A {@code null} value is
      *         permitted, and indicates that the cause is nonexistent or
      *         unknown.)
      */
-    public VersionRetrievalException(Throwable cause) {
-        super(cause);
+    public VersionRetrievalException(Artifact artifact, Throwable cause) {
+        this(null, artifact, cause);
     }
 
     /**
@@ -69,12 +81,22 @@ public class VersionRetrievalException extends Exception {
      *
      * @param  message the detail message (which is saved for later retrieval
      *         by the {@link #getMessage()} method).
+     * @param artifact {@link Artifact} instance causing the problem
      * @param  cause the cause (which is saved for later retrieval by the
      *         {@link #getCause()} method).  (A {@code null} value is
      *         permitted, and indicates that the cause is nonexistent or
      *         unknown.)
      */
-    public VersionRetrievalException(String message, Throwable cause) {
+    public VersionRetrievalException(String message, Artifact artifact, Throwable cause) {
         super(message, cause);
+        this.artifact = artifact;
+    }
+
+    /**
+     * Returns the artifact causing the problem with version retrieval, if available
+     * @return {@link Optional} object containing artifact causing the problem with version retrieval, or empty
+     */
+    public Optional<Artifact> getArtifact() {
+        return Optional.ofNullable(artifact);
     }
 }
diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/utils/MavenProjectUtils.java b/versions-common/src/main/java/org/codehaus/mojo/versions/utils/MavenProjectUtils.java
index e54df949..c1c28939 100644
--- a/versions-common/src/main/java/org/codehaus/mojo/versions/utils/MavenProjectUtils.java
+++ b/versions-common/src/main/java/org/codehaus/mojo/versions/utils/MavenProjectUtils.java
@@ -113,19 +113,15 @@ public class MavenProjectUtils {
                                 .orElse(Stream.empty()));
 
         // log and try to correct versions where they don't appear in the original pom.xml
-        try {
-            return dependencies
-                    .peek(dependency -> log.debug("dependency from pom: "
-                            + dependency.getGroupId() + ":" + dependency.getArtifactId() + ":" + dependency.getVersion()
-                            + ":" + dependency.getScope()))
-                    .map(dependency -> dependency.getVersion() != null
-                            ? interpolateVersion(dependency, project)
-                            : getVersionFromParent(dependency, project, processDependencyManagementTransitive, log)
-                                    .orElse(dependency))
-                    .collect(() -> new TreeSet<>(DependencyComparator.INSTANCE), Set::add, Set::addAll);
-        } catch (IllegalArgumentException e) {
-            throw new VersionRetrievalException(e.getMessage());
-        }
+        return dependencies
+                .peek(dependency -> log.debug("dependency from pom: "
+                        + dependency.getGroupId() + ":" + dependency.getArtifactId() + ":" + dependency.getVersion()
+                        + ":" + dependency.getScope()))
+                .map(dependency -> dependency.getVersion() != null
+                        ? interpolateVersion(dependency, project)
+                        : getVersionFromParent(dependency, project, processDependencyManagementTransitive, log)
+                                .orElse(dependency))
+                .collect(() -> new TreeSet<>(DependencyComparator.INSTANCE), Set::add, Set::addAll);
     }
 
     /**
diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractDependencyUpdatesReport.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractDependencyUpdatesReport.java
index 0c5c1132..afad3488 100644
--- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractDependencyUpdatesReport.java
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractDependencyUpdatesReport.java
@@ -197,17 +197,17 @@ public abstract class AbstractDependencyUpdatesReport extends AbstractVersionsRe
 
             renderReport(locale, sink, model);
         } catch (VersionRetrievalException e) {
-            throw new RuntimeException(e);
+            throw new MavenReportException(e.getMessage(), e);
         }
     }
 
     protected void handleDependencyManagementTransitive(
-            MavenProject project, Set<Dependency> dependencyManagementCollector) {
+            MavenProject project, Set<Dependency> dependencyManagementCollector) throws MavenReportException {
         try {
             dependencyManagementCollector.addAll(MavenProjectUtils.extractDependenciesFromDependencyManagement(
                     project, processDependencyManagementTransitive, getLog()));
         } catch (VersionRetrievalException e) {
-            throw new RuntimeException(e);
+            throw new MavenReportException(e.getMessage(), e);
         }
     }
 
diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesAggregateReport.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesAggregateReport.java
index 6717879f..c7c5150d 100644
--- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesAggregateReport.java
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesAggregateReport.java
@@ -26,6 +26,7 @@ import org.apache.maven.model.Dependency;
 import org.apache.maven.plugins.annotations.Mojo;
 import org.apache.maven.plugins.annotations.ResolutionScope;
 import org.apache.maven.project.MavenProject;
+import org.apache.maven.reporting.MavenReportException;
 import org.apache.maven.wagon.Wagon;
 import org.codehaus.mojo.versions.reporting.ReportRendererFactory;
 import org.codehaus.mojo.versions.reporting.util.AggregateReportUtils;
@@ -70,7 +71,8 @@ public class DependencyUpdatesAggregateReport extends AbstractDependencyUpdatesR
      * {@inheritDoc}
      * */
     @Override
-    protected void populateDependencyManagement(Set<Dependency> dependencyManagementCollector) {
+    protected void populateDependencyManagement(Set<Dependency> dependencyManagementCollector)
+            throws MavenReportException {
         for (MavenProject project : AggregateReportUtils.getProjectsToProcess(getProject())) {
             getLog().debug(String.format("Collecting managed dependencies for project %s", project.getName()));
             handleDependencyManagementTransitive(project, dependencyManagementCollector);
diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesReport.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesReport.java
index 1eddea2b..59c80c51 100644
--- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesReport.java
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DependencyUpdatesReport.java
@@ -27,6 +27,7 @@ import java.util.Set;
 import org.apache.maven.model.Dependency;
 import org.apache.maven.plugins.annotations.Mojo;
 import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.reporting.MavenReportException;
 import org.apache.maven.wagon.Wagon;
 import org.codehaus.mojo.versions.reporting.ReportRendererFactory;
 import org.codehaus.mojo.versions.utils.ArtifactFactory;
@@ -66,7 +67,8 @@ public class DependencyUpdatesReport extends AbstractDependencyUpdatesReport {
      * {@inheritDoc}
      * */
     @Override
-    protected void populateDependencyManagement(Set<Dependency> dependencyManagementCollector) {
+    protected void populateDependencyManagement(Set<Dependency> dependencyManagementCollector)
+            throws MavenReportException {
         if (hasDependencyManagement(getProject())) {
             getLog().debug(String.format(
                     "Collecting managed dependencies for project %s",
diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseDepVersionMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseDepVersionMojo.java
index 88ff5ec0..27db9a40 100644
--- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseDepVersionMojo.java
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseDepVersionMojo.java
@@ -283,7 +283,9 @@ public class UseDepVersionMojo extends AbstractVersionsDependencyUpdaterMojo {
                     "Unable to parse the pom " + node.getModel().getPomFile(), e);
         } catch (VersionRetrievalException e) {
             throw new MojoFailureException(
-                    "Unable to retrieve a dependency version while processing "
+                    "Unable to retrieve dependency versions "
+                            + e.getArtifact().map(a -> "of " + a).orElse("")
+                            + " while processing "
                             + node.getModel().getPomFile(),
                     e);
         }
diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseReleasesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseReleasesMojo.java
index bad39d39..c240fae0 100644
--- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseReleasesMojo.java
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseReleasesMojo.java
@@ -194,8 +194,8 @@ public class UseReleasesMojo extends AbstractVersionsDependencyUpdaterMojo {
                 // Force releaseVersion version because org.apache.maven.artifact.metadata.MavenMetadataSource does not
                 // retrieve release version if provided snapshot version.
                 artifact.setVersion(releaseVersion);
-                Optional<String> targetVersion = findReleaseVersion(
-                        pom, dep, version, releaseVersion, getHelper().lookupArtifactVersions(artifact, false));
+                Optional<String> targetVersion =
+                        findReleaseVersion(releaseVersion, getHelper().lookupArtifactVersions(artifact, false));
                 if (targetVersion.isPresent()) {
                     updateDependencyVersion(pom, dep, targetVersion.get(), changeKind);
                 } else {
@@ -209,12 +209,7 @@ public class UseReleasesMojo extends AbstractVersionsDependencyUpdaterMojo {
         }
     }
 
-    private Optional<String> findReleaseVersion(
-            MutableXMLStreamReader pom,
-            Dependency dep,
-            String version,
-            String releaseVersion,
-            ArtifactVersions versions) {
+    private Optional<String> findReleaseVersion(String releaseVersion, ArtifactVersions versions) {
         return !allowRangeMatching
                 ? versions.containsVersion(releaseVersion) ? Optional.of(releaseVersion) : Optional.empty()
                 : Arrays.stream(versions.getVersions(false))


Test patch:
diff --git a/versions-common/src/test/java/org/codehaus/mojo/versions/ordering/BoundArtifactVersionTest.java b/versions-common/src/test/java/org/codehaus/mojo/versions/ordering/BoundArtifactVersionTest.java
index 11233937..9310a4c6 100644
--- a/versions-common/src/test/java/org/codehaus/mojo/versions/ordering/BoundArtifactVersionTest.java
+++ b/versions-common/src/test/java/org/codehaus/mojo/versions/ordering/BoundArtifactVersionTest.java
@@ -34,6 +34,7 @@ import static org.hamcrest.Matchers.lessThan;
  * Unit tests for {@link BoundArtifactVersion}
  */
 class BoundArtifactVersionTest {
+
     @Test
     void testMajorUpperBoundGreaterThanNextMajor() {
         BoundArtifactVersion bound = new BoundArtifactVersion("1.2.3", MAJOR);
diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestVersionsMojoBase.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestVersionsMojoBase.java
index 36eca236..e8f44d12 100644
--- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestVersionsMojoBase.java
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestVersionsMojoBase.java
@@ -24,6 +24,7 @@ import java.util.Collection;
 import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -60,6 +61,7 @@ public abstract class UseLatestVersionsMojoBase extends AbstractVersionsDependen
 
     /**
      * Number of executor threads for update retrieval.
+     *
      * @since 2.19.0
      */
     @Parameter(property = "numThreads", defaultValue = "5")
@@ -95,10 +97,12 @@ public abstract class UseLatestVersionsMojoBase extends AbstractVersionsDependen
      */
     private abstract static class ArtifactVersionChange {
         private final DependencyChangeRecord.ChangeKind changeKind;
+
         private final String newVersion;
 
         /**
          * Creates a new instance
+         *
          * @param changeKind change kind
          * @param newVersion new version
          */
@@ -130,6 +134,7 @@ public abstract class UseLatestVersionsMojoBase extends AbstractVersionsDependen
 
         /**
          * Constructs a new instance
+         *
          * @param changeKind change kind
          * @param dependency {@code Dependency} instance
          * @param newVersion new version
@@ -199,12 +204,15 @@ public abstract class UseLatestVersionsMojoBase extends AbstractVersionsDependen
             }
         } catch (IOException e) {
             throw new MojoExecutionException(e.getMessage(), e);
-        } catch (IllegalStateException e) {
-            if (e.getCause() instanceof MojoExecutionException) {
-                throw (MojoExecutionException) e.getCause();
-            }
-            if (e.getCause() instanceof VersionRetrievalException) {
-                throw (VersionRetrievalException) e.getCause();
+        } catch (CompletionException e) {
+            if (e.getCause() instanceof IllegalStateException) {
+                IllegalStateException ise = (IllegalStateException) e.getCause();
+                if (ise.getCause() instanceof MojoExecutionException) {
+                    throw (MojoExecutionException) ise.getCause();
+                }
+                if (ise.getCause() instanceof VersionRetrievalException) {
+                    throw (VersionRetrievalException) ise.getCause();
+                }
             }
             throw e;
         }
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DependencyUpdatesReportTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DependencyUpdatesReportTest.java
index 64ca69d5..fa78e368 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DependencyUpdatesReportTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DependencyUpdatesReportTest.java
@@ -28,6 +28,7 @@ import java.util.HashMap;
 import java.util.Locale;
 import java.util.Set;
 
+import org.apache.maven.artifact.Artifact;
 import org.apache.maven.doxia.module.xhtml5.Xhtml5SinkFactory;
 import org.apache.maven.doxia.sink.SinkFactory;
 import org.apache.maven.model.Dependency;
@@ -36,6 +37,7 @@ import org.apache.maven.model.Model;
 import org.apache.maven.plugin.MojoExecution;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.reporting.MavenReportException;
+import org.codehaus.mojo.versions.api.VersionRetrievalException;
 import org.codehaus.mojo.versions.model.RuleSet;
 import org.codehaus.mojo.versions.reporting.ReportRendererFactoryImpl;
 import org.codehaus.mojo.versions.utils.ArtifactFactory;
@@ -56,7 +58,10 @@ import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.anyOf;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
 import static org.hamcrest.Matchers.matchesPattern;
+import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
 
 /**
@@ -389,4 +394,26 @@ public class DependencyUpdatesReportTest {
                 .withProcessDependencyManagementTransitive(false)
                 .generate(sinkFactory.createSink(os), sinkFactory, Locale.getDefault());
     }
+
+    /*
+     * error while attempting a retrieval of a problematic artifact should be reported citing the artifact
+     * causing the problem
+     */
+    @Test
+    public void testProblemCausingArtifact() throws IOException, MavenReportException {
+        OutputStream os = new ByteArrayOutputStream();
+        SinkFactory sinkFactory = new Xhtml5SinkFactory();
+        try {
+            new TestDependencyUpdatesReport()
+                    .withOriginalDependencyManagement(dependencyOf("problem-causing-artifact", "1"))
+                    .withProcessDependencyManagement(true)
+                    .withProcessDependencyManagementTransitive(false)
+                    .generate(sinkFactory.createSink(os), sinkFactory, Locale.getDefault());
+            fail("Should throw an exception");
+        } catch (MavenReportException e) {
+            assertThat(e.getCause(), instanceOf(VersionRetrievalException.class));
+            VersionRetrievalException vre = (VersionRetrievalException) e.getCause();
+            assertThat(vre.getArtifact().map(Artifact::getArtifactId).orElse(""), equalTo("problem-causing-artifact"));
+        }
+    }
 }
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojoTest.java
index 4dd83122..092c2a7b 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojoTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojoTest.java
@@ -22,6 +22,7 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 
+import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
 import org.apache.maven.model.InputLocation;
 import org.apache.maven.model.InputSource;
@@ -32,6 +33,7 @@ import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.plugin.testing.AbstractMojoTestCase;
 import org.apache.maven.plugin.testing.MojoRule;
 import org.apache.maven.project.MavenProject;
+import org.codehaus.mojo.versions.api.VersionRetrievalException;
 import org.codehaus.mojo.versions.filtering.WildcardMatcher;
 import org.codehaus.mojo.versions.model.TestIgnoreVersions;
 import org.codehaus.mojo.versions.utils.ArtifactFactory;
@@ -56,7 +58,9 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.anyOf;
 import static org.hamcrest.Matchers.containsInAnyOrder;
 import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.instanceOf;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.not;
 import static org.hamcrest.Matchers.notNullValue;
@@ -593,4 +597,27 @@ public class DisplayDependencyUpdatesMojoTest extends AbstractMojoTestCase {
             assertThat(output, containsString("1.0.0 -> 2.0.0"));
         }
     }
+
+    /*
+     * error while attempting a retrieval of a problematic artifact should be reported citing the artifact
+     * causing the problem
+     */
+    @Test
+    public void testProblemCausingArtifact() throws Exception {
+        try (CloseableTempFile tempFile = new CloseableTempFile("display-dependency-updates")) {
+            DisplayDependencyUpdatesMojo mojo = (DisplayDependencyUpdatesMojo) mojoRule.lookupConfiguredMojo(
+                    new File("src/test/resources/org/codehaus/mojo/display-dependency-updates/problem-causing"),
+                    "display-dependency-updates");
+            mojo.setPluginContext(new HashMap<>());
+            mojo.outputFile = tempFile.getPath().toFile();
+            mojo.outputEncoding = Charset.defaultCharset().toString();
+            mojo.repositorySystem = mockAetherRepositorySystem();
+            mojo.execute();
+            fail("Should throw an exception");
+        } catch (MojoExecutionException e) {
+            assertThat(e.getCause(), instanceOf(VersionRetrievalException.class));
+            VersionRetrievalException vre = (VersionRetrievalException) e.getCause();
+            assertThat(vre.getArtifact().map(Artifact::getArtifactId).orElse(""), equalTo("problem-causing-artifact"));
+        }
+    }
 }
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayExtensionUpdatesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayExtensionUpdatesMojoTest.java
index 4f019cc4..71b8cc38 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayExtensionUpdatesMojoTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayExtensionUpdatesMojoTest.java
@@ -22,6 +22,7 @@ import java.nio.file.Path;
 import java.util.Collections;
 import java.util.HashMap;
 
+import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
 import org.apache.maven.model.Build;
 import org.apache.maven.model.Model;
@@ -31,6 +32,7 @@ import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.project.MavenProject;
 import org.codehaus.mojo.versions.api.PomHelper;
+import org.codehaus.mojo.versions.api.VersionRetrievalException;
 import org.codehaus.mojo.versions.utils.ArtifactFactory;
 import org.codehaus.mojo.versions.utils.ExtensionBuilder;
 import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
@@ -51,6 +53,9 @@ import static org.codehaus.mojo.versions.utils.MockUtils.mockMavenSession;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.mockStatic;
@@ -280,4 +285,31 @@ public class DisplayExtensionUpdatesMojoTest {
 
         assertThat(String.join("", Files.readAllLines(tempPath)), containsString("1.0.0 -> 1.0.1"));
     }
+
+    @Test
+    public void testProblemCausingArtifact()
+            throws MojoExecutionException, MojoFailureException, IOException, IllegalAccessException {
+        setVariableValueToObject(mojo, "extensionExcludes", emptyList());
+        setVariableValueToObject(mojo, "extensionIncludes", singletonList("*"));
+        mojo.getProject().setBuild(new Build());
+        mojo.getProject()
+                .getBuild()
+                .setExtensions(Collections.singletonList(ExtensionBuilder.newBuilder()
+                        .withGroupId("default-group")
+                        .withArtifactId("problem-causing-artifact")
+                        .withVersion("1.0.0")
+                        .build()));
+
+        try (MockedStatic<PomHelper> pomHelper = mockStatic(PomHelper.class)) {
+            pomHelper
+                    .when(() -> PomHelper.getChildModels(ArgumentMatchers.any(MavenProject.class), any()))
+                    .then(i -> Collections.singletonMap(null, ((MavenProject) i.getArgument(0)).getModel()));
+            mojo.execute();
+            fail("Should throw an exception");
+        } catch (MojoExecutionException e) {
+            assertThat(e.getCause(), instanceOf(VersionRetrievalException.class));
+            VersionRetrievalException vre = (VersionRetrievalException) e.getCause();
+            assertThat(vre.getArtifact().map(Artifact::getArtifactId).orElse(""), equalTo("problem-causing-artifact"));
+        }
+    }
 }
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayParentUpdatesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayParentUpdatesMojoTest.java
index 90d133a0..8d23d08f 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayParentUpdatesMojoTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayParentUpdatesMojoTest.java
@@ -55,10 +55,13 @@ import static org.codehaus.mojo.versions.utils.MockUtils.mockAetherRepositorySys
 import static org.codehaus.mojo.versions.utils.MockUtils.mockArtifactHandlerManager;
 import static org.codehaus.mojo.versions.utils.MockUtils.mockMavenSession;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.hamcrest.Matchers.nullValue;
 import static org.hamcrest.Matchers.stringContainsInOrder;
+import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
 import static org.mockito.MockitoAnnotations.openMocks;
 
@@ -389,4 +392,23 @@ public class DisplayParentUpdatesMojoTest {
                 String.join("", Files.readAllLines(tempFile)),
                 stringContainsInOrder("The parent project is the latest version:", "dummy-parent2", "[,3.0-!)"));
     }
+
+    @Test
+    public void testProblemCausingArtifact() throws MojoFailureException {
+        mojo.getProject().setParent(new MavenProject() {
+            {
+                setGroupId("default-group");
+                setArtifactId("problem-causing-artifact");
+                setVersion("1.0.0");
+            }
+        });
+        try {
+            mojo.execute();
+            fail("Should throw an exception");
+        } catch (MojoExecutionException e) {
+            assertThat(e.getCause(), instanceOf(VersionRetrievalException.class));
+            VersionRetrievalException vre = (VersionRetrievalException) e.getCause();
+            assertThat(vre.getArtifact().map(Artifact::getArtifactId).orElse(""), equalTo("problem-causing-artifact"));
+        }
+    }
 }
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayPluginUpdatesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayPluginUpdatesMojoTest.java
index 61c79ac7..d8df28e0 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayPluginUpdatesMojoTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayPluginUpdatesMojoTest.java
@@ -23,6 +23,7 @@ import java.util.List;
 
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.model.Prerequisites;
+import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.testing.AbstractMojoTestCase;
 import org.apache.maven.plugin.testing.MojoRule;
 import org.apache.maven.project.MavenProject;
@@ -30,6 +31,7 @@ import org.apache.maven.project.ProjectBuilder;
 import org.apache.maven.project.ProjectBuildingException;
 import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.project.ProjectBuildingResult;
+import org.codehaus.mojo.versions.api.VersionRetrievalException;
 import org.codehaus.mojo.versions.utils.TestUtils;
 import org.junit.After;
 import org.junit.Before;
@@ -40,7 +42,9 @@ import static org.apache.commons.codec.CharEncoding.UTF_8;
 import static org.codehaus.mojo.versions.utils.MockUtils.mockAetherRepositorySystem;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.instanceOf;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.mock;
@@ -162,4 +166,21 @@ public class DisplayPluginUpdatesMojoTest extends AbstractMojoTestCase {
         List<String> output = Files.readAllLines(outputPath);
         assertThat(output, hasItem(containsString("Using the minimum version of Maven: 3.3.9")));
     }
+
+    @Test
+    public void testProblemCausingArtifact() throws Exception {
+        Files.copy(
+                Paths.get("src/test/resources/org/codehaus/mojo/display-plugin-updates/problem-causing.xml"),
+                tempDir.resolve("pom.xml"));
+
+        DisplayPluginUpdatesMojo mojo = createMojo();
+        try {
+            mojo.execute();
+            fail("Should throw an exception");
+        } catch (MojoExecutionException e) {
+            assertThat(e.getCause(), instanceOf(VersionRetrievalException.class));
+            VersionRetrievalException vre = (VersionRetrievalException) e.getCause();
+            assertThat(vre.getArtifact().map(Artifact::getArtifactId).orElse(""), equalTo("problem-causing-artifact"));
+        }
+    }
 }
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayPropertyUpdatesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayPropertyUpdatesMojoTest.java
index f6114ec8..9cbb9549 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayPropertyUpdatesMojoTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayPropertyUpdatesMojoTest.java
@@ -14,13 +14,17 @@ package org.codehaus.mojo.versions;
  * limitations under the License.
  */
 
+import java.io.File;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.HashMap;
 
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.testing.AbstractMojoTestCase;
 import org.apache.maven.plugin.testing.MojoRule;
+import org.codehaus.mojo.versions.api.VersionRetrievalException;
 import org.codehaus.mojo.versions.utils.TestUtils;
 import org.junit.After;
 import org.junit.Before;
@@ -31,6 +35,8 @@ import static org.apache.commons.codec.CharEncoding.UTF_8;
 import static org.codehaus.mojo.versions.utils.MockUtils.mockAetherRepositorySystem;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
 import static org.hamcrest.Matchers.matchesPattern;
 import static org.hamcrest.Matchers.not;
 
@@ -131,4 +137,23 @@ public class DisplayPropertyUpdatesMojoTest extends AbstractMojoTestCase {
     public void testAllowUpdatesFromLesserSegmentsSubIncremental() throws Exception {
         testAllowUpdatesFromLesserSegments("1.0.0-1");
     }
+
+    @Test
+    public void testProblemCausingArtifact() throws Exception {
+        try {
+            File projectDir = new File("src/test/resources/org/codehaus/mojo/update-properties/problem-causing");
+            DisplayPropertyUpdatesMojo mojo =
+                    (DisplayPropertyUpdatesMojo) mojoRule.lookupConfiguredMojo(projectDir, "display-property-updates");
+            mojo.outputEncoding = UTF_8;
+            mojo.outputFile = tempFile.toFile();
+            mojo.setPluginContext(new HashMap<>());
+            mojo.repositorySystem = mockAetherRepositorySystem();
+            mojo.execute();
+            fail("Should throw an exception");
+        } catch (MojoExecutionException e) {
+            assertThat(e.getCause(), instanceOf(VersionRetrievalException.class));
+            VersionRetrievalException vre = (VersionRetrievalException) e.getCause();
+            assertThat(vre.getArtifact().map(Artifact::getArtifactId).orElse(""), equalTo("problem-causing-artifact"));
+        }
+    }
 }
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/ParentUpdatesReportTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/ParentUpdatesReportTest.java
index d7318e6c..70413d2b 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/ParentUpdatesReportTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/ParentUpdatesReportTest.java
@@ -35,6 +35,7 @@ import org.apache.maven.plugin.MojoExecution;
 import org.apache.maven.plugin.testing.stubs.DefaultArtifactHandlerStub;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.reporting.MavenReportException;
+import org.codehaus.mojo.versions.api.VersionRetrievalException;
 import org.codehaus.mojo.versions.reporting.ReportRendererFactoryImpl;
 import org.codehaus.mojo.versions.utils.ArtifactFactory;
 import org.codehaus.plexus.i18n.I18N;
@@ -46,6 +47,9 @@ import static org.codehaus.mojo.versions.utils.MockUtils.mockMavenSession;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
 
 /**
@@ -111,4 +115,52 @@ public class ParentUpdatesReportTest {
                         containsString("2.0.0"),
                         containsString("2.0.1-SNAPSHOT")));
     }
+
+    @Test
+    public void testProblemCausingArtifact() throws IOException, MavenReportException {
+        OutputStream os = new ByteArrayOutputStream();
+        SinkFactory sinkFactory = new Xhtml5SinkFactory();
+        try {
+            new ParentUpdatesReport(
+                    MOCK_I18N,
+                    mock(ArtifactFactory.class),
+                    mockAetherRepositorySystem(),
+                    null,
+                    new ReportRendererFactoryImpl(MOCK_I18N)) {
+                {
+                    project = new MavenProject(new Model() {
+                        {
+                            setGroupId("default-group");
+                            setArtifactId("child-artifact");
+                            setVersion("1.0.0");
+                        }
+                    });
+                    project.setParent(new MavenProject(new Model() {
+                        {
+                            setGroupId("default-group");
+                            setArtifactId("problem-causing-artifact");
+                            setVersion("1.0.0");
+                        }
+                    }));
+                    reactorProjects = new ArrayList<>();
+                    project.setParentArtifact(new DefaultArtifact(
+                            project.getParent().getGroupId(),
+                            project.getParent().getArtifactId(),
+                            project.getParent().getVersion(),
+                            Artifact.SCOPE_COMPILE,
+                            "pom",
+                            "default",
+                            new DefaultArtifactHandlerStub("default")));
+
+                    session = mockMavenSession();
+                    mojoExecution = mock(MojoExecution.class);
+                }
+            }.generate(sinkFactory.createSink(os), sinkFactory, Locale.getDefault());
+            fail("Should throw an exception");
+        } catch (MavenReportException e) {
+            assertThat(e.getCause(), instanceOf(VersionRetrievalException.class));
+            VersionRetrievalException vre = (VersionRetrievalException) e.getCause();
+            assertThat(vre.getArtifact().map(Artifact::getArtifactId).orElse(""), equalTo("problem-causing-artifact"));
+        }
+    }
 }
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/PluginUpdatesReportTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/PluginUpdatesReportTest.java
index be9e2718..30311052 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/PluginUpdatesReportTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/PluginUpdatesReportTest.java
@@ -28,6 +28,7 @@ import java.util.HashMap;
 import java.util.Locale;
 import java.util.Set;
 
+import org.apache.maven.artifact.Artifact;
 import org.apache.maven.doxia.module.xhtml5.Xhtml5SinkFactory;
 import org.apache.maven.doxia.sink.SinkFactory;
 import org.apache.maven.model.Build;
@@ -36,6 +37,7 @@ import org.apache.maven.model.PluginManagement;
 import org.apache.maven.plugin.MojoExecution;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.reporting.MavenReportException;
+import org.codehaus.mojo.versions.api.VersionRetrievalException;
 import org.codehaus.mojo.versions.model.RuleSet;
 import org.codehaus.mojo.versions.reporting.ReportRendererFactoryImpl;
 import org.codehaus.mojo.versions.utils.ArtifactFactory;
@@ -52,7 +54,10 @@ import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.anyOf;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
 import static org.hamcrest.Matchers.matchesPattern;
+import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
 
 /**
@@ -209,4 +214,22 @@ public class PluginUpdatesReportTest {
                 os.toString().replaceAll("\\s", " ").replaceAll("<[^>]+>", " ").replaceAll("&[^;]+;", " ");
         assertThat(output, matchesPattern(".*\\breport.overview.numNewerVersionAvailable\\s+0\\b.*"));
     }
+
+    @Test
+    public void testProblemCausingArtifact() throws IOException {
+        OutputStream os = new ByteArrayOutputStream();
+        SinkFactory sinkFactory = new Xhtml5SinkFactory();
+        try {
+            new TestPluginUpdatesReport()
+                    .withPlugins(pluginOf("problem-causing-artifact"))
+                    .withOnlyUpgradable(true)
+                    .withOnlyProjectPlugins(true)
+                    .generate(sinkFactory.createSink(os), sinkFactory, Locale.getDefault());
+            fail("Should throw an exception");
+        } catch (MavenReportException e) {
+            assertThat(e.getCause(), instanceOf(VersionRetrievalException.class));
+            VersionRetrievalException vre = (VersionRetrievalException) e.getCause();
+            assertThat(vre.getArtifact().map(Artifact::getArtifactId).orElse(""), equalTo("problem-causing-artifact"));
+        }
+    }
 }
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/PropertyUpdatesReportTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/PropertyUpdatesReportTest.java
index b41eb443..d1c04354 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/PropertyUpdatesReportTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/PropertyUpdatesReportTest.java
@@ -23,11 +23,15 @@ import java.io.File;
 import java.io.OutputStream;
 import java.util.Locale;
 
+import org.apache.maven.artifact.Artifact;
 import org.apache.maven.doxia.module.xhtml5.Xhtml5SinkFactory;
 import org.apache.maven.doxia.sink.SinkFactory;
 import org.apache.maven.doxia.tools.SiteTool;
+import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.testing.AbstractMojoTestCase;
 import org.apache.maven.plugin.testing.MojoRule;
+import org.apache.maven.reporting.MavenReportException;
+import org.codehaus.mojo.versions.api.VersionRetrievalException;
 import org.eclipse.aether.RepositorySystem;
 import org.junit.Rule;
 import org.junit.Test;
@@ -36,6 +40,8 @@ import static org.codehaus.mojo.versions.utils.MockUtils.mockAetherRepositorySys
 import static org.codehaus.mojo.versions.utils.MockUtils.mockSiteTool;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
 import static org.hamcrest.Matchers.not;
 
 /**
@@ -87,4 +93,27 @@ public class PropertyUpdatesReportTest extends AbstractMojoTestCase {
                 .replaceAll("\\s+", " ");
         assertThat(output, not(containsString("${ver}")));
     }
+
+    @Test
+    public void testProblemCausingArtifact() throws Exception {
+        OutputStream os = new ByteArrayOutputStream();
+        SinkFactory sinkFactory = new Xhtml5SinkFactory();
+
+        PropertyUpdatesReport mojo = (PropertyUpdatesReport) mojoRule.lookupConfiguredMojo(
+                new File("src/test/resources/org/codehaus/mojo/update-properties/problem-causing"),
+                "property-updates-report");
+        setVariableValueToObject(mojo, "siteTool", SITE_TOOL);
+        setVariableValueToObject(mojo, "repositorySystem", AETHER_REPOSITORY_SYSTEM);
+
+        try {
+            mojo.generate(sinkFactory.createSink(os), sinkFactory, Locale.getDefault());
+            fail("Should throw an exception");
+        } catch (MavenReportException e) {
+            assertThat(e.getCause(), instanceOf(MojoExecutionException.class));
+            MojoExecutionException moe = (MojoExecutionException) e.getCause();
+            assertThat(moe.getCause(), instanceOf(VersionRetrievalException.class));
+            VersionRetrievalException vre = (VersionRetrievalException) moe.getCause();
+            assertThat(vre.getArtifact().map(Artifact::getArtifactId).orElse(""), equalTo("problem-causing-artifact"));
+        }
+    }
 }
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UpdatePropertiesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UpdatePropertiesMojoTest.java
index 1ad8ec54..70d5265d 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UpdatePropertiesMojoTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UpdatePropertiesMojoTest.java
@@ -105,4 +105,9 @@ public class UpdatePropertiesMojoTest extends UpdatePropertiesMojoTestBase {
         mojo.execute();
         assertThat(changeRecorder.getChanges(), is(empty()));
     }
+
+    @Test
+    public void testProblemCausingArtifact() throws Exception {
+        testProblemCausingArtifact("update-properties");
+    }
 }
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UpdatePropertiesMojoTestBase.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UpdatePropertiesMojoTestBase.java
index 9a4f0732..3af96ae0 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UpdatePropertiesMojoTestBase.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UpdatePropertiesMojoTestBase.java
@@ -18,12 +18,18 @@ package org.codehaus.mojo.versions;
  * under the License.
  */
 
+import java.io.File;
 import java.nio.file.Path;
 import java.util.HashMap;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
 
+import org.apache.maven.artifact.Artifact;
 import org.apache.maven.plugin.Mojo;
+import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.testing.AbstractMojoTestCase;
 import org.apache.maven.plugin.testing.MojoRule;
+import org.codehaus.mojo.versions.api.VersionRetrievalException;
 import org.codehaus.mojo.versions.utils.TestChangeRecorder;
 import org.eclipse.aether.RepositorySystem;
 import org.junit.After;
@@ -33,6 +39,9 @@ import org.junit.Rule;
 import static org.codehaus.mojo.versions.utils.MockUtils.mockAetherRepositorySystem;
 import static org.codehaus.mojo.versions.utils.TestUtils.createTempDir;
 import static org.codehaus.mojo.versions.utils.TestUtils.tearDownTempDir;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
 
 /**
  * Base class for {@link UpdatePropertiesMojo} and {@link UpdatePropertyMojo} test suites
@@ -76,4 +85,20 @@ public abstract class UpdatePropertiesMojoTestBase extends AbstractMojoTestCase
 
         return (T) mojo;
     }
+
+    @SuppressWarnings("unchecked")
+    protected <T extends Mojo> void testProblemCausingArtifact(String goal, Consumer<Mojo>... initializers)
+            throws Exception {
+        File projectDir = new File("src/test/resources/org/codehaus/mojo/update-properties/problem-causing");
+        T mojo = (T) mojoRule.lookupConfiguredMojo(projectDir, goal);
+        Stream.of(initializers).forEach(m -> m.accept(mojo));
+        try {
+            mojo.execute();
+            fail("Should throw an exception");
+        } catch (MojoExecutionException e) {
+            assertThat(e.getCause(), instanceOf(VersionRetrievalException.class));
+            VersionRetrievalException vre = (VersionRetrievalException) e.getCause();
+            assertThat(vre.getArtifact().map(Artifact::getArtifactId).orElse(""), equalTo("problem-causing-artifact"));
+        }
+    }
 }
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UpdatePropertyMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UpdatePropertyMojoTest.java
index 03bf68b6..815b0741 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UpdatePropertyMojoTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UpdatePropertyMojoTest.java
@@ -76,4 +76,9 @@ public class UpdatePropertyMojoTest extends UpdatePropertiesMojoTestBase {
                 Matchers.hasItem(
                         new DefaultDependencyVersionChange("default-group", "default-artifact", "1.0.0", "1.0.1-rc1")));
     }
+
+    @Test
+    public void testProblemCausingArtifact() throws Exception {
+        testProblemCausingArtifact("update-property", m -> ((UpdatePropertyMojo) m).property = "artifact-version");
+    }
 }
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseDepVersionMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseDepVersionMojoTest.java
index e8ac9e68..8dffafae 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseDepVersionMojoTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseDepVersionMojoTest.java
@@ -15,15 +15,19 @@ package org.codehaus.mojo.versions;
  *  limitations under the License.
  */
 
+import java.io.File;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Collections;
 
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.plugin.logging.SystemStreamLog;
 import org.apache.maven.plugin.testing.AbstractMojoTestCase;
 import org.apache.maven.plugin.testing.MojoRule;
+import org.codehaus.mojo.versions.api.VersionRetrievalException;
 import org.codehaus.mojo.versions.change.DefaultDependencyVersionChange;
 import org.codehaus.mojo.versions.change.DefaultPropertyVersionChange;
 import org.codehaus.mojo.versions.utils.TestChangeRecorder;
@@ -37,7 +41,9 @@ import static org.codehaus.mojo.versions.utils.MockUtils.mockAetherRepositorySys
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.instanceOf;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
@@ -416,4 +422,18 @@ public class UseDepVersionMojoTest extends AbstractMojoTestCase {
                 changeRecorder.getChanges(),
                 hasItem(new DefaultDependencyVersionChange("default-group", "artifactA", "1.0.0", "2.0.0")));
     }
+
+    @Test
+    public void testProblemCausingArtifact() throws Exception {
+        File projectDir = new File("src/test/resources/org/codehaus/mojo/use-dep-version/problem-causing");
+        UseDepVersionMojo mojo = (UseDepVersionMojo) mojoRule.lookupConfiguredMojo(projectDir, "use-dep-version");
+        try {
+            mojo.execute();
+            fail("Should throw an exception");
+        } catch (MojoFailureException e) {
+            assertThat(e.getCause(), instanceOf(VersionRetrievalException.class));
+            VersionRetrievalException vre = (VersionRetrievalException) e.getCause();
+            assertThat(vre.getArtifact().map(Artifact::getArtifactId).orElse(""), equalTo("problem-causing-artifact"));
+        }
+    }
 }
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseLatestVersionsMojoTestBase.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseLatestVersionsMojoTestBase.java
index 70977f96..0c3387d2 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseLatestVersionsMojoTestBase.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseLatestVersionsMojoTestBase.java
@@ -6,7 +6,9 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 
+import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
+import org.apache.maven.model.Model;
 import org.apache.maven.plugin.MojoExecution;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
@@ -27,12 +29,14 @@ import org.mockito.Mock;
 import org.mockito.MockedStatic;
 import org.mockito.Mockito;
 
+import static java.util.Collections.singletonList;
 import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE;
 import static org.apache.maven.plugin.testing.ArtifactStubFactory.setVariableValueToObject;
 import static org.codehaus.mojo.versions.utils.MockUtils.mockAetherRepositorySystem;
 import static org.codehaus.mojo.versions.utils.MockUtils.mockArtifactHandlerManager;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.hasItem;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.not;
@@ -198,4 +202,34 @@ public abstract class UseLatestVersionsMojoTestBase {
                     VersionRetrievalException {
         testExcludeFilter("2.0");
     }
+
+    @Test
+    public void testBreakingDependency() throws Exception {
+        mojo.setProject(new MavenProject() {
+            {
+                setModel(new Model() {
+                    {
+                        setGroupId("default-group");
+                        setArtifactId("project-artifact");
+                        setVersion("1.0.0-SNAPSHOT");
+
+                        setDependencies(singletonList(DependencyBuilder.newBuilder()
+                                .withGroupId("default-group")
+                                .withArtifactId("problem-causing-artifact")
+                                .withVersion("1.0.0")
+                                .withScope(SCOPE_COMPILE)
+                                .withType("jar")
+                                .withClassifier("default")
+                                .build()));
+                    }
+                });
+            }
+        });
+
+        try {
+            tryUpdate();
+        } catch (VersionRetrievalException e) {
+            assertThat(e.getArtifact().map(Artifact::getArtifactId).orElse(""), equalTo("problem-causing-artifact"));
+        }
+    }
 }
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseReleasesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseReleasesMojoTest.java
index e8a07a31..00beb1b7 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseReleasesMojoTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseReleasesMojoTest.java
@@ -2,6 +2,7 @@ package org.codehaus.mojo.versions;
 
 import javax.xml.stream.XMLStreamException;
 
+import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.DefaultArtifact;
 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
 import org.apache.maven.execution.MavenSession;
@@ -33,6 +34,7 @@ import static org.codehaus.mojo.versions.utils.MockUtils.mockAetherRepositorySys
 import static org.codehaus.mojo.versions.utils.MockUtils.mockArtifactHandlerManager;
 import static org.codehaus.mojo.versions.utils.MockUtils.mockMavenSession;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.hasItem;
 import static org.hamcrest.Matchers.startsWith;
 import static org.mockito.ArgumentMatchers.any;
@@ -228,4 +230,25 @@ public class UseReleasesMojoTest extends AbstractMojoTestCase {
             assertThat(e.getMessage(), startsWith("No matching"));
         }
     }
+
+    @Test
+    public void testBreakingDependency() throws Exception {
+        mojo.repositorySystem = mockAetherRepositorySystem();
+        mojo.getProject()
+                .setDependencies(singletonList(DependencyBuilder.newBuilder()
+                        .withGroupId("default-group")
+                        .withArtifactId("problem-causing-artifact")
+                        .withVersion("1.0.0-SNAPSHOT")
+                        .build()));
+
+        try (MockedStatic<PomHelper> pomHelper = mockStatic(PomHelper.class)) {
+            pomHelper
+                    .when(() -> PomHelper.getRawModel(any(MavenProject.class)))
+                    .thenReturn(mojo.getProject().getModel());
+            mojo.update(null);
+            fail("VersionRetrievalException is expected");
+        } catch (VersionRetrievalException e) {
+            assertThat(e.getArtifact().map(Artifact::getArtifactId).orElse(""), equalTo("problem-causing-artifact"));
+        }
+    }
 }
diff --git a/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-dependency-updates/problem-causing/pom.xml b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-dependency-updates/problem-causing/pom.xml
new file mode 100644
index 00000000..49c4a220
--- /dev/null
+++ b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-dependency-updates/problem-causing/pom.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>test-group</groupId>
+    <artifactId>test-artifact</artifactId>
+    <version>DEVELOP-SNAPSHOT</version>
+
+    <dependencies>
+        <dependency>
+            <groupId>test-group</groupId>
+            <artifactId>problem-causing-artifact</artifactId>
+            <version>1</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-plugin-updates/problem-causing.xml b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-plugin-updates/problem-causing.xml
new file mode 100644
index 00000000..aded821b
--- /dev/null
+++ b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-plugin-updates/problem-causing.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>test-group</groupId>
+    <artifactId>test-artifact</artifactId>
+    <version>DEVELOP-SNAPSHOT</version>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>default-group</groupId>
+                <artifactId>problem-causing-artifact</artifactId>
+                <version>1.0.0</version>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/versions-maven-plugin/src/test/resources/org/codehaus/mojo/update-properties/problem-causing/pom.xml b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/update-properties/problem-causing/pom.xml
new file mode 100644
index 00000000..27aa4628
--- /dev/null
+++ b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/update-properties/problem-causing/pom.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>test-group</groupId>
+    <artifactId>test-artifact</artifactId>
+    <version>DEVELOP-SNAPSHOT</version>
+
+    <properties>
+        <artifact-version>1.0.0</artifact-version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>test-group</groupId>
+            <artifactId>problem-causing-artifact</artifactId>
+            <version>${artifact-version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
diff --git a/versions-maven-plugin/src/test/resources/org/codehaus/mojo/use-dep-version/problem-causing/pom.xml b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/use-dep-version/problem-causing/pom.xml
new file mode 100644
index 00000000..0c1add50
--- /dev/null
+++ b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/use-dep-version/problem-causing/pom.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>test-group</groupId>
+    <artifactId>test-artifact</artifactId>
+    <version>DEVELOP-SNAPSHOT</version>
+
+    <dependencies>
+        <dependency>
+            <groupId>test-group</groupId>
+            <artifactId>problem-causing-artifact</artifactId>
+            <version>1</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>versions-maven-plugin</artifactId>
+                <configuration>
+                    <includesList>test-group:problem-causing-artifact</includesList>
+                    <depVersion>2</depVersion>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>