Skip to content

Improve error reporting#1983

Open
kwin wants to merge 2 commits into
masterfrom
bugfix/improve-error-reporting-of-doclet
Open

Improve error reporting#1983
kwin wants to merge 2 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.

Add unit tests to check error reporting
@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

reportError(e.getDocTreePath(), e.getMessage());
} catch (RuntimeException e) {
DocTreePath rootPath = new DocTreePath(docTrees.getPath(field), docComment);
reportError(rootPath, e.getMessage());

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.

Low-severity: The DocTreePath constructor calls Objects.requireNonNull on the DocCommentTree parameter, so if docComment is null when a RuntimeException is caught here, the catch block itself would NPE and mask the original error.

In resolver mode this is unreachable (early return on null docComment), but processMavenField does not guard against null docComment in the same way. Interestingly, buildTagPath (line 355–361 in this PR) already applies exactly this defensive pattern.

Suggested change
reportError(rootPath, e.getMessage());
} catch (RuntimeException e) {
DocTreePath rootPath =
docComment != null ? new DocTreePath(docTrees.getPath(field), docComment) : null;
reportError(rootPath, e.getMessage());

@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

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