Skip to content

Improve error reporting - #1983

Merged
kwin merged 6 commits into
masterfrom
bugfix/improve-error-reporting-of-doclet
Aug 17, 2026
Merged

Improve error reporting#1983
kwin merged 6 commits into
masterfrom
bugfix/improve-error-reporting-of-doclet

Conversation

@kwin

@kwin kwin commented Jul 20, 2026

Copy link
Copy Markdown
Member

Add unit tests to check error reporting

Following this checklist to help us incorporate your
contribution quickly and easily:

  • Your pull request should address just one issue, without pulling in other changes.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Each commit in the pull request should have a meaningful subject line and body.
    Note that commits might be squashed by a maintainer on merge.
  • Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied.
    This may not always be possible but is a best-practice.
  • Run mvn verify to make sure basic checks pass.
    A more thorough check will be performed on your pull request automatically.
  • You have run the integration tests successfully (mvn -Prun-its verify).

If your pull request is about ~20 lines of code you don't need to sign an
Individual Contributor License Agreement if you are unsure
please ask on the developers list.

To make clear that you license your contribution under
the Apache License Version 2.0, January 2004
you have to acknowledge this by using the following check-box.

@kwin
kwin marked this pull request as ready for review July 20, 2026 12:13
@kwin
kwin requested review from cstamas and gnodet July 20, 2026 13:55
@kwin kwin added the build Pull requests that change the build process label Jul 20, 2026

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice work on the error-reporting improvements, @kwin — the continue-on-error pattern with precise DocTreePath locations is a big UX improvement for developers debugging their javadoc tags. The DocTreePathAwareRuntimeException is a clean solution, and I especially like that you fixed the pre-existing bug where extractClassLink hardcoded "@configurationDefaultValue" in error messages even when called for the @configurationType tag.

One thing caught my attention:

Behavioral regression: fields without @configurationDefaultValue are now silently dropped

In processResolverField, the new null guard:

String defValue = resolveDefaultValue(type, field, docComment, blockTags.get("configurationDefaultValue"));
if (defValue == null) {
    // Error was already reported, skip this field
    return;
}

changes behavior for fields that have @configurationSource but no @configurationDefaultValue tag. On master, resolveDefaultValue returned null for a missing tag, but the field was still included via nvl(defValue, "") producing an empty default value string. After this PR, the field is silently skipped.

This affects real configuration keys in the codebase — a quick check shows at least:

File @configurationSource @configurationDefaultValue
ClasspathTransporterFactory.java 1 0
DefaultOfflineController.java 3 0
GnupgConfigurationKeys.java 5 4

The comment "Error was already reported" is also not accurate — when contentTag is null (tag absent), resolveDefaultValue returns null silently without reporting anything.

Suggested fix: remove the if (defValue == null) return; guard and keep the original nvl(defValue, "") handling when building the entry. The null return from resolveDefaultValue for a missing tag is a valid "no default" case, not an error. The actual error case (unresolvable link) already throws DocTreePathAwareRuntimeException and is caught by the per-field catch blocks.

Minor nits:

  • There's a stray blank line in extractClassLink between the if condition and the throw statement
  • The top-level run() catch lost the stack trace (e.printStackTrace(reporter.getStandardWriter()) was removed) — for truly unexpected failures (NPEs, etc.), the stack trace is valuable for diagnosis

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

gnodet added a commit to gnodet/maven-resolver that referenced this pull request Jul 20, 2026
@cstamas

cstamas commented Jul 20, 2026

Copy link
Copy Markdown
Member

And as can be seen on 2.0.21 release: https://maven.apache.org/resolver-archives/resolver-LATEST/configuration.html

Not all "Source" (last column) values are handled, there are some uninterpolated values left.

image

Unsure is this help or renderer issue, but it should be replaced with "Java System Properties", as currently Resolver config is sourced from two places:

  • session config properties (main source)
  • Java system properties (early ones, usually during object graph construction, when there is no session yet)

gnodet added a commit to gnodet/maven-resolver that referenced this pull request Jul 20, 2026
@gnodet

gnodet commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Thanks for the follow-up commit, @kwin — the "Don't skip field without default values" fix directly addresses the behavioral regression I flagged in my review.

Verified: processResolverField no longer has the early return on null defValue, and instead flows through nvl(defValue, "") — matching the master branch behavior. Fields like ClasspathTransporterFactory.CONFIG_PROP_CLASSPATH_MANAGER, DefaultOfflineController's three keys, and GnupgConfigurationKeys.GPGCONF_* will now be correctly included in the generated properties with empty default values, as before.

The rest of the changes (continue-on-error pattern with DocTreePathAwareRuntimeException, precise DocTreePath locations, updated tests) look solid. CI is running on the new commit — will check back when it completes.

This comment was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

gnodet added a commit to gnodet/maven-resolver that referenced this pull request Jul 20, 2026

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Solid error-reporting improvement. The continue-on-error pattern with precise DocTreePath locations is a well-designed improvement over the fail-fast approach. Good test coverage with CapturingDiagnosticsListener.

The second commit correctly fixed the behavioral regression where fields without @configurationDefaultValue were being silently dropped. CI passes across all matrix combinations.

Minor observations (not blockers):

  • The generic RuntimeException catch block (line 169) constructs a DocTreePath with docComment, but docComment can be null when processing maven-mode fields — a guard would prevent masking the real error with an NPE.
  • The run() catch block no longer prints stack traces for unexpected failures — worth preserving for diagnostic value.
  • Stray blank line in extractClassLink (line 480) and minor javadoc typo in the test ("the a fixture" → "a fixture").

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of gnodet

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Re-review: The regression flagged in the previous review (skipping fields without default values) was correctly fixed in the follow-up commit — nice work! The continue-on-error pattern with precise DocTreePath locations is well-designed and tested. One minor defensive-coding suggestion below.

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of gnodet

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Well-designed continue-on-error pattern with precise DocTreePath error locations. The regression from commit 1 was correctly fixed in commit 2. CI passes across all matrix combinations. A few observations:

Medium severity:

  • 🐛 NPE risk in error handler (line 168): The generic RuntimeException catch constructs new DocTreePath(docTrees.getPath(field), docComment) without null-checking docComment. The DocTreePath constructor calls Objects.requireNonNull on its DocCommentTree parameter, so when docComment is null (possible in maven mode), this will throw NPE and mask the original exception. The buildTagPath helper already has this null guard — the same pattern should be applied here.

Low severity:

  • The top-level run() catch block no longer prints stack traces (e.printStackTrace was removed). For truly unexpected failures (NPEs, ClassCastExceptions), the stack trace is the primary diagnostic artifact.
  • Stray blank line between the if condition and the throw statement in extractClassLink.
  • Javadoc typo: "Classpath location of the a fixture" should be "Classpath location of a fixture".

Strengths:

  • The DocTreePathAwareRuntimeException pattern allows reporting all errors at once rather than failing on the first one — significant UX improvement.
  • The hardcoded "@configurationDefaultValue" fix in extractClassLink resolves a pre-existing bug.
  • The collectBlockTags return type refactor is clean and enables precise error locations.

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of Guillaume Nodet

@cstamas cstamas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we get this rebased?

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Well-structured improvement to error reporting in ConfigurationCollectorDoclet. The switch from opaque exception propagation to precise source-location-aware diagnostics via the Javadoc Reporter API is a nice improvement, and the fix for the hardcoded @configurationDefaultValue tag name in extractClassLink error messages is correct. Good test coverage for error paths.

One minor note: the outer catch in run() replaced e.printStackTrace() with reportError(), which only reports the message. For truly unexpected RuntimeExceptions that escape doRun(), the stack trace loss could make debugging harder. Consider including the exception class name or cause.

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of gnodet

@kwin
kwin marked this pull request as draft August 8, 2026 09:27
Use enum for mode parameter
Streamline calculation of DocTreePath
@kwin
kwin force-pushed the bugfix/improve-error-reporting-of-doclet branch from 9ef10f6 to 3bffe58 Compare August 11, 2026 07:57
@kwin
kwin marked this pull request as ready for review August 15, 2026 13:41
@kwin
kwin force-pushed the bugfix/improve-error-reporting-of-doclet branch from 0e5a2a7 to 508bf20 Compare August 15, 2026 13:48

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Re-review after new commits

Previously flagged NPE risk (null docComment) is now fixed — nice work on the null-check at lines 213-217.

Two correctness bugs found in the new commits — see inline comments.

Additionally:

  • getFullyQualifiedName(field) (lines 310/389) returns only the enclosing type's FQN, dropping the field name. Master produced type.getQualifiedName() + "." + field.getSimpleName() (e.g. org.eclipse.aether.ConnectorKeys.CONFIG_PROP_THREADS). Consider adding a visitVariable override or appending "." + field.getSimpleName() at the call site.
  • Minor: javadoc typo "the a fixture" (test line 57), empty @return tag (line 330), run() catch still loses stack trace (line 191, low impact since doRun() now handles most exceptions per-field).

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of Guillaume Nodet

@kwin
kwin force-pushed the bugfix/improve-error-reporting-of-doclet branch from 937ed82 to 6d6008f Compare August 17, 2026 08:08
@kwin
kwin requested a review from gnodet August 17, 2026 08:11
@kwin
kwin force-pushed the bugfix/improve-error-reporting-of-doclet branch from 6d6008f to 92c8ac6 Compare August 17, 2026 08:12

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Re-review (3rd pass): The three bugs flagged in the previous review (mode assignment, Objects.toString on Optional, getFullyQualifiedName dropping field name) are all correctly fixed — nice work! One remaining observation below about the getSince fallback behavior.

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of Guillaume Nodet

since = getSinceTag(docTrees.getDocCommentTree(type), null);
DocTreePath parentPath = path.getParentPath();
if (parentPath != null) {
return getSince(parentPath);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The getSince fallback to the enclosing type's @since tag may no longer work correctly. The old code explicitly called docTrees.getDocCommentTree(type) to look up the TYPE's doc comment when a field lacked its own @since tag. The refactored code recurses via DocTreePath.getParentPath(), but rootPath (constructed at the top of the processing loop) is a root DocTreePath whose getParentPath() returns null per JDK API contract, so this fallback branch never executes.

This would affect configuration key classes where fields inherit @since from the enclosing type — for example, GnupgConfigurationKeys has @since 2.0.0 on the class with 5 config fields that have no field-level @since, and ConfigurationProperties has many more such fields. These fields would produce empty since values in the generated documentation.

Worth verifying that the generated output still includes since values for inherited cases.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Indeed, added a test case and fixed the issue in 39dd159.

@kwin
kwin force-pushed the bugfix/improve-error-reporting-of-doclet branch from 39dd159 to 9bcf30a Compare August 17, 2026 09:50

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Re-review (4th pass): All four previously flagged issues are now resolved:

  1. ✅ Mode assignment bug (discarded valueOf result) — fixed
  2. Objects.toString on Optional producing garbage — fixed
  3. getFullyQualifiedName dropping field name — fixed
  4. getSince fallback to enclosing type's @since — fixed with proper Element hierarchy traversal and test coverage via package-info.java

The getSince inheritance fix is well-designed — using the Element hierarchy (field → class → package → module) instead of DocTreePath.getParentPath() correctly models Java's documentation inheritance semantics.

Two non-blocking nits:

  • The assertion message "no @since expected" at line 109 of ConfigurationCollectorDocletTest.java is now stale since the expected value changed to "2.0" — consider updating to clarify inheritance from package-info.java
  • package-info.java test fixture is missing a final newline

This review was generated by an AI agent and may contain inaccuracies. Please verify all suggestions before applying.

Claude Code on behalf of Guillaume Nodet

@kwin
kwin merged commit ed4a939 into master Aug 17, 2026
24 checks passed
@kwin
kwin deleted the bugfix/improve-error-reporting-of-doclet branch August 17, 2026 10:30
@github-actions github-actions Bot added this to the 2.0.22 milestone Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build Pull requests that change the build process

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants