You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by kw...@apache.org on 2026/07/19 16:17:46 UTC

(maven-resolver) branch bugfix/improve-error-reporting-of-doclet created (now 461a2b3be)

This is an automated email from the ASF dual-hosted git repository.

kwin pushed a change to branch bugfix/improve-error-reporting-of-doclet
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git


      at 461a2b3be Improve error reporting

This branch includes the following new commits:

     new 461a2b3be Improve error reporting

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(maven-resolver) 01/01: Improve error reporting

Posted by kw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kwin pushed a commit to branch bugfix/improve-error-reporting-of-doclet
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git

commit 461a2b3be968889b6fc25bf3a6d92eab6f338042
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Sun Jul 19 18:17:33 2026 +0200

    Improve error reporting
---
 .../aether/tools/ConfigurationCollectorDoclet.java | 137 ++++++++++++++++-----
 1 file changed, 106 insertions(+), 31 deletions(-)

diff --git a/maven-resolver-tools/src/main/java/org/eclipse/aether/tools/ConfigurationCollectorDoclet.java b/maven-resolver-tools/src/main/java/org/eclipse/aether/tools/ConfigurationCollectorDoclet.java
index 75a7401e4..7aea2fe2a 100644
--- a/maven-resolver-tools/src/main/java/org/eclipse/aether/tools/ConfigurationCollectorDoclet.java
+++ b/maven-resolver-tools/src/main/java/org/eclipse/aether/tools/ConfigurationCollectorDoclet.java
@@ -133,15 +133,15 @@ public class ConfigurationCollectorDoclet implements Doclet {
         try {
             return doRun(environment);
         } catch (RuntimeException e) {
-            reporter.print(Diagnostic.Kind.ERROR, "Error running ConfigurationCollectorDoclet: " + e.getMessage());
-            e.printStackTrace(reporter.getStandardWriter());
+            reportError("Error running ConfigurationCollectorDoclet: " + e.getMessage());
             return false;
         }
     }
 
     private boolean doRun(DocletEnvironment environment) {
         if (output == null) {
-            throw new IllegalStateException("Missing required --output option");
+            reportError("Missing required --output option");
+            return false;
         }
         docTrees = environment.getDocTrees();
         List<Map<String, String>> discoveredKeys = new ArrayList<>();
@@ -153,20 +153,68 @@ public class ConfigurationCollectorDoclet implements Doclet {
                     continue;
                 }
                 DocCommentTree docComment = docTrees.getDocCommentTree(field);
-                if ("maven".equals(mode)) {
-                    processMavenField(type, field, docComment, discoveredKeys);
-                } else if ("resolver".equals(mode)) {
-                    processResolverField(type, field, docComment, discoveredKeys);
-                } else {
-                    throw new IllegalArgumentException("Unknown mode: " + mode);
+                try {
+                    if ("maven".equals(mode)) {
+                        processMavenField(type, field, docComment, discoveredKeys);
+                    } else if ("resolver".equals(mode)) {
+                        processResolverField(type, field, docComment, discoveredKeys);
+                    } else {
+                        reportError(field, "Unknown mode: " + mode);
+                    }
+                } catch (IllegalArgumentException e) {
+                    reportError(field, e.getMessage());
+                } catch (RuntimeException e) {
+                    reportError(field, "Failed to process: " + e.getMessage());
                 }
             }
         }
 
-        writeProperties(discoveredKeys);
+        try {
+            writeProperties(discoveredKeys);
+        } catch (UncheckedIOException e) {
+            reportError("Failed to write properties file: " + e.getMessage());
+            return false;
+        }
         return true;
     }
 
+    /**
+     * Reports an error message at a specific element location.
+     *
+     * @param element the element where the error occurred
+     * @param message the error message
+     */
+    private void reportError(Element element, String message) {
+        if (element != null) {
+            reporter.print(Diagnostic.Kind.ERROR, element, message);
+        } else {
+            reportError(message);
+        }
+    }
+
+    /**
+     * Reports an error message at a specific DocTreePath location.
+     *
+     * @param path the DocTreePath where the error occurred
+     * @param message the error message
+     */
+    private void reportError(DocTreePath path, String message) {
+        if (path != null) {
+            reporter.print(Diagnostic.Kind.ERROR, path, message);
+        } else {
+            reportError(message);
+        }
+    }
+
+    /**
+     * Reports a global error message without location information.
+     *
+     * @param message the error message
+     */
+    private void reportError(String message) {
+        reporter.print(Diagnostic.Kind.ERROR, message);
+    }
+
     private void processResolverField(
             TypeElement type, VariableElement field, DocCommentTree docComment, List<Map<String, String>> discovered) {
         if (docComment == null) {
@@ -177,9 +225,15 @@ public class ConfigurationCollectorDoclet implements Doclet {
             return;
         }
 
-        String configurationType =
-                getConfigurationType(extractClassLink(field, docComment, blockTags.get("configurationType")));
-        String defValue = resolveDefaultValue(type, field, docComment, blockTags.get("configurationDefaultValue"));
+        String configurationType = getConfigurationType(
+                extractClassLink(field, docComment, blockTags, "configurationType"));
+        String defValue =
+                resolveDefaultValue(type, field, docComment, blockTags.get("configurationDefaultValue"));
+
+        if (defValue == null) {
+            // Error was already reported, skip this field
+            return;
+        }
 
         Map<String, String> entry = new LinkedHashMap<>();
         entry.put("key", String.valueOf(field.getConstantValue()));
@@ -216,8 +270,8 @@ public class ConfigurationCollectorDoclet implements Doclet {
             Object value = attribute.getValue().getValue();
             switch (name) {
                 case "source":
-                    source = value instanceof VariableElement
-                            ? ((VariableElement) value).getSimpleName().toString()
+                    source = value instanceof VariableElement variableElement
+                            ? variableElement.getSimpleName().toString()
                             : String.valueOf(value);
                     break;
                 case "defaultValue":
@@ -304,9 +358,8 @@ public class ConfigurationCollectorDoclet implements Doclet {
     private Map<String, List<? extends DocTree>> collectBlockTags(DocCommentTree docComment) {
         Map<String, List<? extends DocTree>> result = new LinkedHashMap<>();
         for (DocTree tag : docComment.getBlockTags()) {
-            if (tag instanceof UnknownBlockTagTree) {
-                UnknownBlockTagTree unknown = (UnknownBlockTagTree) tag;
-                result.put(unknown.getTagName(), unknown.getContent());
+            if (tag instanceof UnknownBlockTagTree unknownBlockTree) {
+                result.put(unknownBlockTree.getTagName(), unknownBlockTree.getContent());
             }
         }
         return result;
@@ -321,8 +374,7 @@ public class ConfigurationCollectorDoclet implements Doclet {
             return null;
         }
         for (DocTree tree : content) {
-            if (tree instanceof LinkTree) {
-                LinkTree link = (LinkTree) tree;
+            if (tree instanceof LinkTree link) {
                 if (link.getReference() != null) {
                     String signature = link.getReference().getSignature();
                     // resolve the referenced constant using the fully qualified signature, so that references
@@ -332,9 +384,20 @@ public class ConfigurationCollectorDoclet implements Doclet {
                             ? lookupConstant(referenced)
                             : lookupConstant(type, signature.substring(signature.indexOf('#') + 1));
                     if (value == null) {
-                        // hard fail as in the original implementation: default value constants must be resolvable
-                        throw new IllegalArgumentException("Could not look up {@link " + signature
-                                + "} for configuration " + type.getQualifiedName());
+                        // hard fail: default value constants must be resolvable
+                        DocTreePath linkPath = resolveDocTreePath(contextField, docComment, link);
+                        if (linkPath != null) {
+                            reportError(
+                                    linkPath,
+                                    "Could not look up {@link " + signature + "} for configuration "
+                                            + type.getQualifiedName());
+                        } else {
+                            reportError(
+                                    contextField,
+                                    "Could not look up {@link " + signature + "} for configuration "
+                                            + type.getQualifiedName());
+                        }
+                        throw new IllegalArgumentException("Could not resolve link: " + signature);
                     }
                     return value;
                 }
@@ -359,7 +422,19 @@ public class ConfigurationCollectorDoclet implements Doclet {
             return null;
         }
         Element element = docTrees.getElement(refPath);
-        return element instanceof VariableElement ? (VariableElement) element : null;
+        return element instanceof VariableElement variableElement ? variableElement : null;
+    }
+
+    /**
+     * Resolves the {@link DocTreePath} for a {@code {@link ...}} reference. Returns {@code null} if the path cannot
+     * be resolved.
+     */
+    private DocTreePath resolveDocTreePath(VariableElement contextField, DocCommentTree docComment, LinkTree link) {
+        if (contextField == null || docComment == null) {
+            return null;
+        }
+        DocTreePath rootPath = new DocTreePath(docTrees.getPath(contextField), docComment);
+        return DocTreePath.getPath(rootPath, link.getReference());
     }
 
     private String lookupConstant(TypeElement type, String constantName) {
@@ -417,9 +492,10 @@ public class ConfigurationCollectorDoclet implements Doclet {
     }
 
     private String extractClassLink(
-            VariableElement contextField, DocCommentTree docComment, List<? extends DocTree> content) {
+            VariableElement contextField, DocCommentTree docComment, Map<String, List<? extends DocTree>> blockTags, String tagName) {
+        List<? extends DocTree> content = blockTags.get(tagName);
         if (content == null || content.isEmpty()) {
-            throw new IllegalArgumentException("Missing content for @configurationDefaultValue");
+            throw new IllegalArgumentException("Missing content for @" + tagName);
         }
         for (DocTree tree : content) {
             // just use the first link, ignore any other content (e.g. text) in the tag
@@ -427,13 +503,12 @@ public class ConfigurationCollectorDoclet implements Doclet {
                 String signature = link.getReference().getSignature();
                 if (signature.contains("#")) {
                     throw new IllegalArgumentException(
-                            "Expected a class link in @configurationDefaultValue, but got a member reference: "
-                                    + signature);
+                            "Expected a class link in @" + tagName + ", but got a member reference: " + signature);
                 }
                 return resolveReferencedType(contextField, docComment, link, signature);
             }
         }
-        throw new IllegalArgumentException("No valid {@link ...} reference found in @configurationDefaultValue");
+        throw new IllegalArgumentException("No valid {@link ...} reference found in @" + tagName);
     }
 
     /**
@@ -452,8 +527,8 @@ public class ConfigurationCollectorDoclet implements Doclet {
             return signature;
         }
         Element element = docTrees.getElement(refPath);
-        return element instanceof TypeElement
-                ? ((TypeElement) element).getQualifiedName().toString()
+        return element instanceof TypeElement typeElement
+                ? typeElement.getQualifiedName().toString()
                 : signature;
     }