Skip to content

fix: write error handling - #425

Open
NguyenHoangSon96 wants to merge 1 commit into
mainfrom
fix/write-error-handling
Open

fix: write error handling#425
NguyenHoangSon96 wants to merge 1 commit into
mainfrom
fix/write-error-handling

Conversation

@NguyenHoangSon96

@NguyenHoangSon96 NguyenHoangSon96 commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Closes #

Proposed Changes

  • How the errors are handled and test cases adjustment in this PR are heavily influenced by this PR.

Changes

  • Reduce the call of objectMapper.readTree(body) function to only once.
  • Tests were modified to accommodate with new definitions of partial write errors, which are:
    - Error response status code is 400.
    - Error response format {"error":"...","data":[{"error_message":"...","line_number":2,"original_line": "..."}]} is returned with data must be an array.
    - accept_partial is set to true.
    - Write endpoint must be api/v3/write_lp.

Checklist

  • CHANGELOG.md updated
  • Rebased/mergeable
  • A test has been added if appropriate
  • Tests pass
  • Commit messages are conventional
  • Sign CLA (if not already signed)

@NguyenHoangSon96 NguyenHoangSon96 self-assigned this Aug 20, 2026
@NguyenHoangSon96
NguyenHoangSon96 force-pushed the fix/write-error-handling branch from ca5ff0d to 78953cb Compare August 21, 2026 08:31
@NguyenHoangSon96
NguyenHoangSon96 marked this pull request as ready for review August 21, 2026 15:07
Copilot AI lite review requested due to automatic review settings August 21, 2026 15:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors how RestClient formats and classifies write-related HTTP error responses (notably InfluxDB 3 write/partial-write formats), and updates unit/integration tests to reflect the new behavior.

Changes:

  • Added an overloaded RestClient.request(...) that propagates acceptPartial / useV2Api flags so partial-write handling can be gated by client options.
  • Reworked write-error parsing to build InfluxDBPartialWriteException details from JSON responses (and adjusted expected messages in tests).
  • Introduced a small Utils.isNumeric helper and expanded unit test coverage with a table-driven set of partial-write cases.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/main/java/com/influxdb/v3/client/internal/RestClient.java Refactors error parsing/exception selection for write endpoints; adds partial-write gating logic.
src/main/java/com/influxdb/v3/client/internal/InfluxDBClientImpl.java Passes acceptPartial / useV2Api flags into RestClient.request(...) for write calls.
src/main/java/com/influxdb/v3/client/internal/Utils.java Adds numeric-check helper used by error parsing.
src/main/java/com/influxdb/v3/client/InfluxDBPartialWriteException.java Adjusts LineError nullability annotations.
src/test/java/com/influxdb/v3/client/internal/RestClientTest.java Updates and expands tests for partial-write parsing/message formatting.
src/test/java/com/influxdb/v3/client/integration/E2ETest.java Updates integration expectation for non-accept-partial write errors.
Suppressed comments (2)

src/main/java/com/influxdb/v3/client/InfluxDBPartialWriteException.java:83

  • Changing LineError.errorMessage to @Nullable is a public API contract change and it’s inconsistent with current callers (tests and RestClient.createErrorMsgDetails) that treat it as always present. If the intent is still that a line error always has an error message, keep it @Nonnull and avoid propagating nulls to API consumers.

This issue also appears on line 95 of the same file.

        public LineError(@Nullable final Integer lineNumber,
                         @Nullable final String errorMessage,
                         @Nullable final String originalLine) {
            this.lineNumber = lineNumber;
            this.errorMessage = errorMessage;
            this.originalLine = originalLine;

src/main/java/com/influxdb/v3/client/InfluxDBPartialWriteException.java:100

  • If errorMessage() is intended to be always present for a LineError, its accessor should stay @Nonnull to match the API contract and existing usage.
         * @return line-level error message
         */
        @Nullable
        public String errorMessage() {
            return errorMessage;
        }

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/main/java/com/influxdb/v3/client/internal/Utils.java Outdated
Comment thread src/main/java/com/influxdb/v3/client/internal/RestClient.java Outdated
Comment thread src/main/java/com/influxdb/v3/client/internal/RestClient.java Outdated
Comment thread src/test/java/com/influxdb/v3/client/internal/RestClientTest.java Outdated
Comment thread src/main/java/com/influxdb/v3/client/internal/RestClient.java Outdated
@NguyenHoangSon96
NguyenHoangSon96 requested a lite review from Copilot August 21, 2026 15:29
@NguyenHoangSon96
NguyenHoangSon96 force-pushed the fix/write-error-handling branch 3 times, most recently from d4a06d2 to 9e7e4cd Compare August 21, 2026 15:33

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Suppressed comments (6)

Previously missed (3) — in code that hasn't changed since the last review.

src/main/java/com/influxdb/v3/client/InfluxDBPartialWriteException.java:82

  • InfluxDBPartialWriteException.LineError#errorMessage was previously non-null in the public API contract. Making it @Nullable is a breaking/loosening change for callers and also increases the risk of NPEs in formatting code that assumes a message exists. Unless null is a valid state that callers must handle, keep this @Nonnull.

This issue also appears on line 97 of the same file.

        public LineError(@Nullable final Integer lineNumber,
                         @Nullable final String errorMessage,
                         @Nullable final String originalLine) {
            this.lineNumber = lineNumber;
            this.errorMessage = errorMessage;

src/main/java/com/influxdb/v3/client/internal/RestClient.java:263

  • if (root == null || root.toString().isEmpty()) is effectively dead code (Jackson returns a non-null node, and toString() won’t be empty). As a result, header-based fallbacks won’t execute anymore for empty bodies. Switching this to a body emptiness check restores the intended fallback behavior.
            if (root == null || root.toString().isEmpty()) {
                reason = Stream.of("X-Platform-Error-Code", "X-Influx-Error", "X-InfluxDb-Error")
                        .map(name -> response.headers().firstValue(name).orElse(null))
                        .filter(message -> message != null && !message.isEmpty()).findFirst()
                        .orElse("");

src/main/java/com/influxdb/v3/client/internal/RestClient.java:243

  • The response Content-Type can include parameters (e.g. text/plain; charset=utf-8). Using strict equality here can cause non-JSON text responses to be routed into JSON parsing unnecessarily. Consider a case-insensitive prefix match instead.
            if (contentType != null && contentType.equals("text/plain")) {
                var message = String.format("HTTP status code: %d; Message: %s", statusCode, body);
                throw new InfluxDBApiHttpException(message, response.headers(), response.statusCode());

src/main/java/com/influxdb/v3/client/internal/RestClient.java:336

  • This method return type uses @NonNull (jspecify), which will fail to compile if jspecify isn’t on the classpath and is also inconsistent with the rest of this class’ javax.annotation.Nonnull usage. Use @Nonnull (or omit the redundant annotation) instead.
    @Nonnull
    private @NonNull List<String> createErrorMsgDetails(
            @Nullable final ParseLineErrorResult result,
            @Nullable final JsonNode root
    ) {

src/test/java/com/influxdb/v3/client/internal/RestClientTest.java:1185

  • @NonNull on toString() requires the jspecify dependency (and isn’t providing much value here). Removing the annotation keeps the test independent of that external annotation library.

    @Override
    public @NonNull String toString() {

src/main/java/com/influxdb/v3/client/InfluxDBPartialWriteException.java:99

  • For consistency with the constructor contract and to avoid forcing callers to handle nulls that should never occur, errorMessage() should remain @Nonnull.
        @Nullable
        public String errorMessage() {
            return errorMessage;

Comment thread src/main/java/com/influxdb/v3/client/internal/RestClient.java
Comment thread src/main/java/com/influxdb/v3/client/internal/RestClient.java
Comment thread src/test/java/com/influxdb/v3/client/internal/RestClientTest.java
@codecov

codecov Bot commented Aug 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.98361% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.41%. Comparing base (06f5d19) to head (fc1eba2).

Files with missing lines Patch % Lines
...va/com/influxdb/v3/client/internal/RestClient.java 90.00% 3 Missing and 8 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #425      +/-   ##
==========================================
- Coverage   88.73%   88.41%   -0.33%     
==========================================
  Files          21       22       +1     
  Lines        1553     1536      -17     
  Branches      281      271      -10     
==========================================
- Hits         1378     1358      -20     
- Misses         77       78       +1     
- Partials       98      100       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Comment thread src/main/java/com/influxdb/v3/client/internal/RestClient.java Outdated
Comment thread src/main/java/com/influxdb/v3/client/internal/RestClient.java Outdated
Comment thread src/test/java/com/influxdb/v3/client/internal/RestClientTest.java Outdated
Comment thread src/main/java/com/influxdb/v3/client/internal/RestClient.java Outdated
@NguyenHoangSon96
NguyenHoangSon96 force-pushed the fix/write-error-handling branch 2 times, most recently from 4428d3b to 5a70263 Compare August 21, 2026 16:31
@NguyenHoangSon96
NguyenHoangSon96 marked this pull request as draft August 24, 2026 06:47
@NguyenHoangSon96
NguyenHoangSon96 requested a lite review from Copilot August 24, 2026 07:28

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Suppressed comments (1)

src/test/java/com/influxdb/v3/client/internal/UtilsTest.java:77

  • This test duplicates coverage already provided by the @NullAndEmptySource in isIntegerInvalid, increasing test noise without adding assertions. Consider removing it and relying on the parameterized test.
    @Test
    void testEmpty() {
        Assertions.assertThat(Utils.isInteger("")).isFalse();
    }

Comment thread src/test/java/com/influxdb/v3/client/internal/UtilsTest.java Outdated
Comment thread src/main/java/com/influxdb/v3/client/internal/RestClient.java Outdated
Comment thread src/main/java/com/influxdb/v3/client/internal/RestClient.java
@NguyenHoangSon96
NguyenHoangSon96 force-pushed the fix/write-error-handling branch 2 times, most recently from 65f0552 to afa8797 Compare August 24, 2026 07:40
@NguyenHoangSon96
NguyenHoangSon96 requested a lite review from Copilot August 24, 2026 07:46

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Suppressed comments (2)

src/main/java/com/influxdb/v3/client/InfluxDBPartialWriteException.java:107

  • LineError.originalLine() is a record component accessor; it does not override any supertype method, so @Override will not compile here. Remove the @Override annotation.
            @Override
            @Nullable
            public String originalLine() {
                return originalLine;
            }

src/main/java/com/influxdb/v3/client/InfluxDBPartialWriteException.java:98

  • LineError.errorMessage() is the record component accessor; the @Override annotation here will not compile, and the accessor should remain @Nonnull to match the constructor contract (line-level error message is required).
            @Override
            @Nullable
            public String errorMessage() {
                return errorMessage;
            }

Comment thread src/main/java/com/influxdb/v3/client/InfluxDBPartialWriteException.java Outdated
@NguyenHoangSon96
NguyenHoangSon96 force-pushed the fix/write-error-handling branch 3 times, most recently from c82babc to 1e8aafc Compare August 24, 2026 08:51
@NguyenHoangSon96
NguyenHoangSon96 force-pushed the fix/write-error-handling branch 2 times, most recently from 3f93a73 to fa7f0c6 Compare August 24, 2026 09:32
@NguyenHoangSon96
NguyenHoangSon96 requested a lite review from Copilot August 24, 2026 09:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Suppressed comments (4)

src/main/java/com/influxdb/v3/client/InfluxDBPartialWriteException.java:78

  • The LineError record allows null errorMessage despite being annotated @nonnull, and the constructor doesn't enforce non-null. This can lead to nulls flowing into error formatting (e.g., message details rendering as "null"). Enforce non-null at construction time.
            public LineError(@Nullable final Integer lineNumber,
                             @Nonnull final String errorMessage,
                             @Nullable final String originalLine) {
                this.lineNumber = lineNumber;
                this.errorMessage = errorMessage;

src/main/java/com/influxdb/v3/client/InfluxDBPartialWriteException.java:96

  • errorMessage() is documented as a required field (and the constructor is annotated @nonnull), but the accessor is annotated @nullable. This is an API contract mismatch for callers; it should be @Nonnull if null is not allowed.
             * @return line-level error message
             */
            @Nullable
            public String errorMessage() {
                return errorMessage;
            }

src/main/java/com/influxdb/v3/client/internal/RestClient.java:348

  • The Javadoc for createErrorMsgDetails says result/root may be null and that the method returns an empty list if they are null, but the parameters are annotated @Nonnull and the implementation doesn't handle nulls. Please align the Javadoc with the actual contract.
     * @param result the parsing result containing details about failed lines; may be null
     * @param root the JSON node representing the response data; may be null
     * @return a list of generated error message details; an empty list if the input parameters are null
     */

src/main/java/com/influxdb/v3/client/internal/RestClient.java:440

  • errIsJsonLikeContentType is now unused after the refactor (the request path always attempts JSON parsing unless Content-Type is text/plain). Keeping an unused private helper adds noise and may fail builds that treat warnings as errors.
    private boolean errIsJsonLikeContentType(@Nullable final String contentType) {
        return contentType == null
                || contentType.isEmpty()
                || contentType.regionMatches(true, 0, "application/json", 0, "application/json".length());
    }

Comment thread src/main/java/com/influxdb/v3/client/internal/RestClient.java Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

src/main/java/com/influxdb/v3/client/InfluxDBPartialWriteException.java:96

  • LineError#errorMessage() is documented/constructed as non-null (@Nonnull ctor param) but the overridden accessor is annotated @Nullable, which weakens the public API contract and may confuse nullness tooling. It should remain @Nonnull (or drop the override entirely and annotate the record component instead).
            /**
             * @return line-level error message
             */
            @Nullable
            public String errorMessage() {
                return errorMessage;
            }

Comment thread src/main/java/com/influxdb/v3/client/internal/RestClient.java
@NguyenHoangSon96
NguyenHoangSon96 force-pushed the fix/write-error-handling branch from 8ea6513 to 11b2036 Compare August 24, 2026 14:13
@NguyenHoangSon96
NguyenHoangSon96 force-pushed the fix/write-error-handling branch from 08b9acd to fc1eba2 Compare August 24, 2026 16:15
@NguyenHoangSon96
NguyenHoangSon96 marked this pull request as ready for review August 24, 2026 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants