Skip to content

*: fix golangci-lint issues and delete unused code#5037

Open
3AceShowHand wants to merge 18 commits into
pingcap:masterfrom
3AceShowHand:fix-ineffassign-nilerr-errorlint
Open

*: fix golangci-lint issues and delete unused code#5037
3AceShowHand wants to merge 18 commits into
pingcap:masterfrom
3AceShowHand:fix-ineffassign-nilerr-errorlint

Conversation

@3AceShowHand
Copy link
Copy Markdown
Collaborator

@3AceShowHand 3AceShowHand commented May 13, 2026

Issue Number: ref #5032

What problem does this PR solve?

Fix multiple categories of golangci-lint issues reported by make check-static, reducing the total from ~300 to ~250.

What is changed and how it works?

Auto-fixes (ineffassign, nilerr):

  • expr_filter.go: remove duplicate FillVirtualColumnValue call
  • consumer.go: remove dead tableName assignment
  • drop_event.go: remove dead offset += 8 before return
  • file.go: return nilreturn err
  • mysql_writer_ddl.go: return nilreturn err
  • pool_test.go: return nilreturn err

errorlint — use errors.Is/errors.As instead of ==/type-assertion (12 files):

  • message_center.go: err != context.DeadlineExceeded!pkgerror.Is(err, context.DeadlineExceeded)
  • etcd_worker_test.go: == context.DeadlineExceededcerrors.Is(..., context.DeadlineExceeded)
  • api_client.go: switch { case context.Canceled }if cerror.Is(..., context.Canceled), simplified if-then-returnreturn !cerror.Is(...)
  • file.go: err != io.EOF!cerror.Is(err, io.EOF)
  • csv_decoder.go: err == io.EOFerrors.Is(err, io.EOF)
  • bank/case.go: != context.Canceled!cerror.Is(..., context.Canceled)
  • helper.go, many_pk_or_uk/main.go, options_test.go: type assertions → errors.As

increment-decrement (7 files):

  • controller.go, dml_event.go, csv_decoder.go, helper.go, sync_point.go etc.: += 1++, -= 1--

unused code deletion (14 files):

  • stream.go: remove streamWrapper type, methods, streamGenerator
  • remote_target.go, errors.go, claim_check.go: remove unused consts/vars
  • cli_changefeed_helper.go: remove readInput
  • active_active.go: remove getSoftDeleteTimeColumnIndex
  • model.go: remove getDefaultVerifyTableConfig, toCredential
  • barrier_event.go, splitter.go, utils.go, message.go, thread_pool_test_task.go, etc.

redefines-builtin-id:

  • atomic.go: rename newnewVal

Config:

  • .golangci.yml: suppress ST1003 (variable naming for legacy identifiers)
  • Makefile: add local-static-check target for branch-diff linting

pkg/errors re-export:

  • reexport.go: add WithStack, ErrorStack, ErrorEqual, NewNoStackError, NotFoundf, NotValidf, Normalize, RFCCodeText, Unwrap, RedactLogEnabled, plus type aliases Error, RFCErrorCode, ErrCode

Check List

Tests:

  • Unit test: go build ./... passes

Code changes:

  • Has Go code changes
  • No new dependencies

Side effects:

  • None

Release note

None

Summary by CodeRabbit

  • Refactor

    • Standardized error handling and matching across the codebase for more reliable wrapped-error detection and logging.
    • Minor style modernizations (increment/operator and unused-parameter cleanups) and removal of test-only helpers.
  • Bug Fixes

    • Improved EOF and resource-close handling to avoid spurious errors.
    • More robust send/notification paths now log warnings on failures instead of silently ignoring them.
  • New Features

    • Canal-JSON messages now expose commit timestamps.
  • Chores

    • Added a local static-code-check target and tightened linter rules.

Review Change Stack

@ti-chi-bot ti-chi-bot Bot added do-not-merge/needs-linked-issue release-note Denotes a PR that will be considered when it comes time to generate release notes. labels May 13, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Standardizes wrapped-error handling (Is/As/Cause), renames unused params to _, applies ++/-- shorthand, adjusts Close/EOF patterns, adds a stream wrapper and topic-manager/mock tweaks, expands pkg/errors re-exports, and makes small behavior-preserving refactors across the repo.

Changes

Repository-wide consistency changes

Layer / File(s) Summary
All changes
multiple files across the repository (see PR diff)
Combined edits converting direct error comparisons/type assertions to wrapped-error-aware checks (errors.Is/errors.As/errors.Cause), renaming unused parameters to _, simplifying arithmetic to ++/--, removing small helpers/imports/constants, consolidating resource-close patterns to explicitly ignore Close errors, introducing streamWrapper/streamGenerator, updating topic-manager mocks/tests, computing virtual-column offsets before filling, and expanding pkg/errors re-exports.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

lgtm, ok-to-test

Suggested reviewers

  • asddongmen
  • wk989898
  • tenfyzhong
  • flowbehappy

Poem

"🧡 I’m a rabbit in the code so spry,
I hopped and wrapped errors with Is and As, oh my!
Underscores tucked parameters neat,
Counters trimmed to ++ — concise and sweet,
A tiny hop — the repo’s tidy, bye-bye!"

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

@3AceShowHand 3AceShowHand marked this pull request as draft May 13, 2026 06:20
@ti-chi-bot ti-chi-bot Bot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels May 13, 2026
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors error handling across several modules, replacing direct error comparisons and type assertions with more robust errors.Is and errors.As patterns, typically using the cerror wrapper. It also cleans up a duplicate line in expr_filter.go and adds a lint suppression in subscription_client.go. The review feedback identifies several instances where the use of errors.Cause(err) is redundant because cerror.Is and cerror.As already handle error unwrapping, and also points out an indentation issue in api_client.go. Addressing these suggestions will improve code idiomaticity and maintainability.

Comment thread pkg/pdutil/api_client.go Outdated
Comment thread pkg/sink/codec/common/helper.go Outdated
Comment thread pkg/orchestrator/etcd_worker_test.go Outdated
Comment thread tests/integration_tests/many_pk_or_uk/main.go Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (5)
tests/integration_tests/bank/case.go (1)

564-564: ⚡ Quick win

Remove redundant errors.Cause() unwrapping before cerror.Is() check.

The pattern cerror.Is(errors.Cause(err), context.Canceled) is redundant because cerror.Is() already traverses the error chain to detect cancellation in wrapped errors. Use cerror.Is(err, context.Canceled) directly.

♻️ Simplify error check
 				err := workload()
-				if err != nil && !cerror.Is(errors.Cause(err), context.Canceled) {
+				if err != nil && !cerror.Is(err, context.Canceled) {
 					log.Warn("workload failed", zap.Error(err))
 				}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration_tests/bank/case.go` at line 564, The error check is using
redundant unwrapping with errors.Cause(err) before calling cerror.Is; update the
condition to call cerror.Is(err, context.Canceled) directly (leave the
surrounding if logic intact) so the wrapped error chain is correctly inspected
without the extra errors.Cause() call; change the expression involving cerror.Is
and errors.Cause to use cerror.Is(err, context.Canceled) referencing the
existing err variable and context.Canceled symbol.
pkg/pdutil/api_client.go (2)

366-366: ⚡ Quick win

Remove redundant errors.Cause() unwrapping before cerror.Is() check.

Same issue as line 190: cerror.Is() already traverses the error chain, so unwrapping with errors.Cause() first is redundant.

♻️ Simplify error check
 	}, retry.WithMaxTries(defaultMaxRetry), retry.WithIsRetryableErr(func(err error) bool {
-		if cerror.Is(errors.Cause(err), context.Canceled) {
+		if cerror.Is(err, context.Canceled) {
 			return false
 		}
 		return true
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/pdutil/api_client.go` at line 366, The check at
cerror.Is(errors.Cause(err), context.Canceled) is redundant because cerror.Is
already walks the error chain; change the call to use the original error
(cerror.Is(err, context.Canceled)) instead of wrapping with errors.Cause(err);
apply the same simplification used earlier (see the similar pattern around the
code that referenced line 190) to remove unnecessary unwrapping and keep
error-chain-aware checks in functions in api_client.go.

190-193: ⚡ Quick win

Remove redundant errors.Cause() unwrapping before cerror.Is() check.

The pattern cerror.Is(errors.Cause(err), context.Canceled) is redundant because cerror.Is() already traverses the error chain to match wrapped errors. Use cerror.Is(err, context.Canceled) directly.

♻️ Simplify error check
 		retry.WithIsRetryableErr(func(err error) bool {
-			if cerror.Is(errors.Cause(err), context.Canceled) {
+			if cerror.Is(err, context.Canceled) {
 			return false
 		}
 		return true
 		}))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/pdutil/api_client.go` around lines 190 - 193, The error check currently
calls cerror.Is(errors.Cause(err), context.Canceled) which redundantly unwraps
the error; change it to call cerror.Is(err, context.Canceled) directly (keeping
the same behavior for the variable err and the context.Canceled sentinel) and
remove any now-unused errors.Cause import if it becomes unused.
pkg/sink/codec/csv/csv_decoder.go (1)

113-113: ⚡ Quick win

Remove redundant errors.Cause() unwrapping before errors.Is() check.

The pattern errors.Is(errors.Cause(err), io.EOF) is redundant because errors.Is() already traverses the error chain to match EOF in wrapped errors. Use errors.Is(err, io.EOF) directly.

♻️ Simplify EOF check
-		if errors.Is(errors.Cause(err), io.EOF) {
+		if errors.Is(err, io.EOF) {
 			return common.MessageTypeUnknown, false
 		}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/sink/codec/csv/csv_decoder.go` at line 113, Replace the redundant
errors.Is(errors.Cause(err), io.EOF) check with errors.Is(err, io.EOF) in the
CSV decoder code: locate the EOF handling in pkg/sink/codec/csv/csv_decoder.go
where the variable err is being checked and change the call to use
errors.Is(err, io.EOF) directly (no errors.Cause unwrap) so the error chain is
properly inspected without redundant unwrapping.
pkg/orchestrator/etcd_worker_test.go (1)

275-276: ⚡ Quick win

Remove redundant errors.Cause() unwrapping before cerrors.Is() check.

The pattern cerrors.Is(errors.Cause(err), target) is redundant because cerrors.Is() already traverses the error chain to match wrapped errors. Unwrapping with errors.Cause() first defeats the purpose of using the wrapped-error-aware Is() check.

♻️ Simplify error checks
-	if err != nil && (cerrors.Is(errors.Cause(err), context.DeadlineExceeded) ||
-		cerrors.Is(errors.Cause(err), context.Canceled) ||
+	if err != nil && (cerrors.Is(err, context.DeadlineExceeded) ||
+		cerrors.Is(err, context.Canceled) ||
 		strings.Contains(err.Error(), "etcdserver: request timeout")) {
 		return
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/orchestrator/etcd_worker_test.go` around lines 275 - 276, The error
checks unnecessarily call errors.Cause(err) before cerrors.Is, which is
redundant because cerrors.Is already walks wrapped errors; update the
conditional in the test to call cerrors.Is(err, context.DeadlineExceeded) and
cerrors.Is(err, context.Canceled) (and any other cerrors.Is checks) directly
instead of cerrors.Is(errors.Cause(err), ...), leaving the rest of the logic in
the function (the conditional around err) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pkg/orchestrator/etcd_worker_test.go`:
- Around line 275-276: The error checks unnecessarily call errors.Cause(err)
before cerrors.Is, which is redundant because cerrors.Is already walks wrapped
errors; update the conditional in the test to call cerrors.Is(err,
context.DeadlineExceeded) and cerrors.Is(err, context.Canceled) (and any other
cerrors.Is checks) directly instead of cerrors.Is(errors.Cause(err), ...),
leaving the rest of the logic in the function (the conditional around err)
unchanged.

In `@pkg/pdutil/api_client.go`:
- Line 366: The check at cerror.Is(errors.Cause(err), context.Canceled) is
redundant because cerror.Is already walks the error chain; change the call to
use the original error (cerror.Is(err, context.Canceled)) instead of wrapping
with errors.Cause(err); apply the same simplification used earlier (see the
similar pattern around the code that referenced line 190) to remove unnecessary
unwrapping and keep error-chain-aware checks in functions in api_client.go.
- Around line 190-193: The error check currently calls
cerror.Is(errors.Cause(err), context.Canceled) which redundantly unwraps the
error; change it to call cerror.Is(err, context.Canceled) directly (keeping the
same behavior for the variable err and the context.Canceled sentinel) and remove
any now-unused errors.Cause import if it becomes unused.

In `@pkg/sink/codec/csv/csv_decoder.go`:
- Line 113: Replace the redundant errors.Is(errors.Cause(err), io.EOF) check
with errors.Is(err, io.EOF) in the CSV decoder code: locate the EOF handling in
pkg/sink/codec/csv/csv_decoder.go where the variable err is being checked and
change the call to use errors.Is(err, io.EOF) directly (no errors.Cause unwrap)
so the error chain is properly inspected without redundant unwrapping.

In `@tests/integration_tests/bank/case.go`:
- Line 564: The error check is using redundant unwrapping with errors.Cause(err)
before calling cerror.Is; update the condition to call cerror.Is(err,
context.Canceled) directly (leave the surrounding if logic intact) so the
wrapped error chain is correctly inspected without the extra errors.Cause()
call; change the expression involving cerror.Is and errors.Cause to use
cerror.Is(err, context.Canceled) referencing the existing err variable and
context.Canceled symbol.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 041c685d-b320-4a15-a94c-26c6c1f6e39e

📥 Commits

Reviewing files that changed from the base of the PR and between af5629f and efd695f.

📒 Files selected for processing (11)
  • logservice/logpuller/subscription_client.go
  • pkg/filter/expr_filter.go
  • pkg/messaging/message_center.go
  • pkg/orchestrator/etcd_worker_test.go
  • pkg/pdutil/api_client.go
  • pkg/redo/reader/file.go
  • pkg/sink/codec/common/helper.go
  • pkg/sink/codec/csv/csv_decoder.go
  • pkg/sink/kafka/options_test.go
  • tests/integration_tests/bank/case.go
  • tests/integration_tests/many_pk_or_uk/main.go
💤 Files with no reviewable changes (1)
  • pkg/filter/expr_filter.go

@ti-chi-bot ti-chi-bot Bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels May 13, 2026
@ti-chi-bot ti-chi-bot Bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels May 13, 2026
3AceShowHand and others added 4 commits May 13, 2026 16:26
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@3AceShowHand 3AceShowHand marked this pull request as ready for review May 13, 2026 08:29
@ti-chi-bot ti-chi-bot Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label May 13, 2026
@3AceShowHand
Copy link
Copy Markdown
Collaborator Author

/test all

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
pkg/sink/codec/common/helper.go (1)

328-329: ⚡ Quick win

Simplify error type checking for consistency.

Line 329 calls errors.Cause(err) before errors.As, but errors.As already unwraps errors internally per Go 1.13+ semantics. This is redundant and inconsistent with line 272 in queryRowChecksumAux, which correctly uses errors.As(err, &mysqlErr) directly.

♻️ Proposed fix to remove redundant unwrapping
 		var mysqlErr *mysqlDriver.MySQLError
-		ok := errors.As(errors.Cause(err), &mysqlErr)
+		ok := errors.As(err, &mysqlErr)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/sink/codec/common/helper.go` around lines 328 - 329, Replace the
redundant unwrapping call in the MySQL error type check: instead of calling
errors.As(errors.Cause(err), &mysqlErr) (where mysqlErr is a
*mysqlDriver.MySQLError), call errors.As(err, &mysqlErr) directly so the
built-in unwrapping semantics are used consistently (as done in
queryRowChecksumAux); update the check in helper.go accordingly.
pkg/sink/kafka/options_test.go (1)

834-835: ⚡ Quick win

Simplify error type checking.

Line 835 calls errors.Cause(err) before errors.As, but errors.As already unwraps errors internally per Go 1.13+ semantics. The redundant errors.Cause call is unnecessary.

♻️ Proposed fix to remove redundant unwrapping
 		var numError *strconv.NumError
-		ok := errors.As(errors.Cause(err), &numError)
+		ok := errors.As(err, &numError)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/sink/kafka/options_test.go` around lines 834 - 835, The test currently
does redundant unwrapping by calling errors.Cause(err) before errors.As; update
the check that declares var numError *strconv.NumError and the call ok :=
errors.As(errors.Cause(err), &numError) to call errors.As directly on err (i.e.,
ok := errors.As(err, &numError)), relying on Go's built-in unwrapping semantics
so strconv.NumError is detected correctly without errors.Cause.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pkg/sink/codec/common/helper.go`:
- Around line 328-329: Replace the redundant unwrapping call in the MySQL error
type check: instead of calling errors.As(errors.Cause(err), &mysqlErr) (where
mysqlErr is a *mysqlDriver.MySQLError), call errors.As(err, &mysqlErr) directly
so the built-in unwrapping semantics are used consistently (as done in
queryRowChecksumAux); update the check in helper.go accordingly.

In `@pkg/sink/kafka/options_test.go`:
- Around line 834-835: The test currently does redundant unwrapping by calling
errors.Cause(err) before errors.As; update the check that declares var numError
*strconv.NumError and the call ok := errors.As(errors.Cause(err), &numError) to
call errors.As directly on err (i.e., ok := errors.As(err, &numError)), relying
on Go's built-in unwrapping semantics so strconv.NumError is detected correctly
without errors.Cause.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8976b863-9641-49b9-9978-ad75436a7423

📥 Commits

Reviewing files that changed from the base of the PR and between ed47a3b and 504289f.

📒 Files selected for processing (13)
  • Makefile
  • downstreamadapter/sink/pulsar/helper.go
  • downstreamadapter/sink/topicmanager/kafka_topic_manager.go
  • downstreamadapter/sink/topicmanager/pulsar_topic_manager.go
  • downstreamadapter/sink/topicmanager/pulsar_topic_manager_mock.go
  • downstreamadapter/sink/topicmanager/pulsar_topic_manager_test.go
  • pkg/errors/reexport.go
  • pkg/messaging/message_center.go
  • pkg/orchestrator/etcd_worker_test.go
  • pkg/pdutil/api_client.go
  • pkg/redo/reader/file.go
  • pkg/sink/codec/common/helper.go
  • pkg/sink/kafka/options_test.go
💤 Files with no reviewable changes (1)
  • downstreamadapter/sink/topicmanager/pulsar_topic_manager.go

@3AceShowHand
Copy link
Copy Markdown
Collaborator Author

/test all

@3AceShowHand 3AceShowHand changed the title *: fix more lint related issue *: fix golangci-lint issues (increment-decrement, unused, errorlint, redefines-builtin-id, etc.) May 13, 2026
@ti-chi-bot ti-chi-bot Bot added release-note-none Denotes a PR that doesn't merit a release note. and removed do-not-merge/needs-linked-issue release-note Denotes a PR that will be considered when it comes time to generate release notes. labels May 13, 2026
@3AceShowHand 3AceShowHand changed the title *: fix golangci-lint issues (increment-decrement, unused, errorlint, redefines-builtin-id, etc.) *: fix golangci-lint issues and delete unused code May 13, 2026
@ti-chi-bot ti-chi-bot Bot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels May 13, 2026
@3AceShowHand
Copy link
Copy Markdown
Collaborator Author

/test all

@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented May 13, 2026

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: tenfyzhong

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ti-chi-bot ti-chi-bot Bot added the needs-1-more-lgtm Indicates a PR needs 1 more LGTM. label May 13, 2026
@ti-chi-bot
Copy link
Copy Markdown

ti-chi-bot Bot commented May 13, 2026

[LGTM Timeline notifier]

Timeline:

  • 2026-05-13 15:12:57.860278401 +0000 UTC m=+278546.393057730: ☑️ agreed by tenfyzhong.

@ti-chi-bot ti-chi-bot Bot added the approved label May 13, 2026
@3AceShowHand
Copy link
Copy Markdown
Collaborator Author

/test all

@3AceShowHand
Copy link
Copy Markdown
Collaborator Author

/test all

@3AceShowHand
Copy link
Copy Markdown
Collaborator Author

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
pkg/check/active_active_tso_indexes.go (1)

173-173: ⚡ Quick win

Consider using predefined errors for better categorization.

These validation errors currently use generic errors.New or errors.Errorf. For consistency and better error handling, consider defining predefined errors for:

  • Inconsistent TSO index values across TiDB instances (lines 173, 186)
  • Missing required TSO config keys (lines 196, 199)

This would enable callers to distinguish between different failure modes using errors.Is().

Also applies to: 186-186, 196-196, 199-199

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/check/active_active_tso_indexes.go` at line 173, Define package-level
sentinel errors (e.g., var ErrInconsistentTSOIndex = errors.New("inconsistent
tso-unique-index across TiDB instances") and var ErrMissingTSOConfigKey =
errors.New("missing required tso config key")) in
pkg/check/active_active_tso_indexes.go and replace the ad-hoc errors.New/Errorsf
returns that currently use the literal messages (for example the return using
"downstream TiDB reports inconsistent tso-unique-index across instances" and the
returns using "missing required tso config key") to return or wrap those
sentinel errors; where additional context (like which key) is helpful, wrap the
sentinel with fmt.Errorf("%w: key=%s", ErrMissingTSOConfigKey, key) so callers
can use errors.Is() to detect ErrInconsistentTSOIndex and
ErrMissingTSOConfigKey.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/sink/mysql/helper.go`:
- Around line 206-209: Replace the direct sentinel comparison against
sql.ErrNoRows with an errors.Is check: in the block where
db.QueryRowContext(...).Scan(&name, &value) is called (the session variable
lookup using variableName), change the condition `err != nil && err !=
sql.ErrNoRows` to use `errors.Is(err, sql.ErrNoRows)` so wrapped ErrNoRows is
handled correctly; update the conditional to `if err != nil && !errors.Is(err,
sql.ErrNoRows) { ... }` (same error wrapping via ErrMySQLQueryError stays
unchanged).

---

Nitpick comments:
In `@pkg/check/active_active_tso_indexes.go`:
- Line 173: Define package-level sentinel errors (e.g., var
ErrInconsistentTSOIndex = errors.New("inconsistent tso-unique-index across TiDB
instances") and var ErrMissingTSOConfigKey = errors.New("missing required tso
config key")) in pkg/check/active_active_tso_indexes.go and replace the ad-hoc
errors.New/Errorsf returns that currently use the literal messages (for example
the return using "downstream TiDB reports inconsistent tso-unique-index across
instances" and the returns using "missing required tso config key") to return or
wrap those sentinel errors; where additional context (like which key) is
helpful, wrap the sentinel with fmt.Errorf("%w: key=%s", ErrMissingTSOConfigKey,
key) so callers can use errors.Is() to detect ErrInconsistentTSOIndex and
ErrMissingTSOConfigKey.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 011d0a1e-d9c7-4cda-9b54-13191f56564e

📥 Commits

Reviewing files that changed from the base of the PR and between 504289f and 4aa4466.

📒 Files selected for processing (55)
  • .golangci.yml
  • api/status/status.go
  • cmd/cdc/cli/cli_changefeed_helper.go
  • cmd/storage-consumer/consumer.go
  • cmd/storage-consumer/main.go
  • coordinator/controller.go
  • coordinator/coordinator_test.go
  • downstreamadapter/dispatchermanager/dispatcher_manager_redo.go
  • downstreamadapter/dispatchermanager/helper.go
  • downstreamadapter/sink/blackhole/sink.go
  • downstreamadapter/sink/pulsar/ddl_producer.go
  • downstreamadapter/sink/pulsar/dml_producer.go
  • downstreamadapter/sink/pulsar/mock_producer.go
  • downstreamadapter/sink/pulsar/sink.go
  • downstreamadapter/sink/redo/sink.go
  • downstreamadapter/sink/topicmanager/kafka_topic_manager.go
  • downstreamadapter/sink/topicmanager/pulsar_topic_manager.go
  • logservice/coordinator/coordinator.go
  • logservice/eventstore/event_store.go
  • logservice/logpuller/subscription_client.go
  • maintainer/testutil/test_util.go
  • pkg/check/active_active_tso_indexes.go
  • pkg/common/log_coordinator.go
  • pkg/diff/checkpoint.go
  • pkg/diff/diff.go
  • pkg/encryption/tikv_http_client.go
  • pkg/errors/helper.go
  • pkg/errors/utils.go
  • pkg/etcd/client.go
  • pkg/eventservice/event_scanner.go
  • pkg/filter/expr_filter.go
  • pkg/filter/utils.go
  • pkg/httputil/httputil.go
  • pkg/logger/log.go
  • pkg/messaging/remote_target.go
  • pkg/redo/reader/file.go
  • pkg/redo/reader/reader.go
  • pkg/retry/retry_test.go
  • pkg/sink/codec/bootstraper.go
  • pkg/sink/kafka/claimcheck/claim_check.go
  • pkg/sink/mysql/config.go
  • pkg/sink/mysql/helper.go
  • pkg/sink/mysql/mysql_writer.go
  • pkg/sink/mysql/mysql_writer_ddl.go
  • pkg/sink/mysql/mysql_writer_dml_exec.go
  • pkg/sink/mysql/mysql_writer_for_active_active_sync_stats.go
  • pkg/sink/mysql/mysql_writer_for_ddl_ts.go
  • pkg/sink/mysql/progress_table_writer.go
  • pkg/sink/mysql/progress_table_writer_test.go
  • pkg/sink/mysql/sql_builder_test.go
  • pkg/tcpserver/tcp_server.go
  • pkg/upstream/manager.go
  • pkg/util/json_writer.go
  • pkg/version/check.go
  • tests/integration_tests/bank/case.go
✅ Files skipped from review due to trivial changes (14)
  • downstreamadapter/sink/pulsar/sink.go
  • downstreamadapter/sink/pulsar/dml_producer.go
  • api/status/status.go
  • pkg/sink/codec/bootstraper.go
  • downstreamadapter/sink/pulsar/ddl_producer.go
  • maintainer/testutil/test_util.go
  • pkg/common/log_coordinator.go
  • downstreamadapter/sink/blackhole/sink.go
  • pkg/sink/mysql/mysql_writer_for_ddl_ts.go
  • downstreamadapter/sink/pulsar/mock_producer.go
  • logservice/eventstore/event_store.go
  • pkg/util/json_writer.go
  • pkg/sink/kafka/claimcheck/claim_check.go
  • downstreamadapter/dispatchermanager/helper.go
🚧 Files skipped from review as they are similar to previous changes (21)
  • downstreamadapter/sink/topicmanager/pulsar_topic_manager.go
  • cmd/storage-consumer/main.go
  • pkg/httputil/httputil.go
  • pkg/diff/checkpoint.go
  • pkg/sink/mysql/mysql_writer_ddl.go
  • coordinator/controller.go
  • logservice/coordinator/coordinator.go
  • pkg/diff/diff.go
  • pkg/sink/mysql/mysql_writer_for_active_active_sync_stats.go
  • pkg/redo/reader/reader.go
  • downstreamadapter/sink/topicmanager/kafka_topic_manager.go
  • pkg/logger/log.go
  • cmd/storage-consumer/consumer.go
  • downstreamadapter/sink/redo/sink.go
  • coordinator/coordinator_test.go
  • pkg/tcpserver/tcp_server.go
  • pkg/filter/utils.go
  • pkg/retry/retry_test.go
  • pkg/errors/utils.go
  • pkg/sink/mysql/mysql_writer.go
  • pkg/redo/reader/file.go

Comment thread pkg/sink/mysql/helper.go
Comment on lines 206 to 209
err := db.QueryRowContext(context.Background(), querySQL).Scan(&name, &value)
if err != nil && err != sql.ErrNoRows {
errMsg := "fail to query session variable " + variableName
return "", cerror.ErrMySQLQueryError.Wrap(err).GenWithStack(errMsg)
return "", errors.ErrMySQLQueryError.Wrap(err).GenWithStack("fail to query session variable %s", variableName)
}
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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Missed errorlint fix: replace direct err != sql.ErrNoRows comparison with errors.Is.

While the adjacent wrap on line 208 was migrated, the sentinel comparison on line 207 still uses ==/!= against sql.ErrNoRows. This is exactly the errorlint pattern this PR is fixing elsewhere (and the AI summary states sql.ErrNoRows is handled via errors.Is in checkTiDBVariable, which doesn't match the code). If Scan ever returns a wrapped sql.ErrNoRows (e.g., from a future driver wrapper or middleware), this branch will misclassify it as a query failure.

🛠️ Proposed fix
 	err := db.QueryRowContext(context.Background(), querySQL).Scan(&name, &value)
-	if err != nil && err != sql.ErrNoRows {
+	if err != nil && !errors.Is(err, sql.ErrNoRows) {
 		return "", errors.ErrMySQLQueryError.Wrap(err).GenWithStack("fail to query session variable %s", variableName)
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
err := db.QueryRowContext(context.Background(), querySQL).Scan(&name, &value)
if err != nil && err != sql.ErrNoRows {
errMsg := "fail to query session variable " + variableName
return "", cerror.ErrMySQLQueryError.Wrap(err).GenWithStack(errMsg)
return "", errors.ErrMySQLQueryError.Wrap(err).GenWithStack("fail to query session variable %s", variableName)
}
err := db.QueryRowContext(context.Background(), querySQL).Scan(&name, &value)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return "", errors.ErrMySQLQueryError.Wrap(err).GenWithStack("fail to query session variable %s", variableName)
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/sink/mysql/helper.go` around lines 206 - 209, Replace the direct sentinel
comparison against sql.ErrNoRows with an errors.Is check: in the block where
db.QueryRowContext(...).Scan(&name, &value) is called (the session variable
lookup using variableName), change the condition `err != nil && err !=
sql.ErrNoRows` to use `errors.Is(err, sql.ErrNoRows)` so wrapped ErrNoRows is
handled correctly; update the conditional to `if err != nil && !errors.Is(err,
sql.ErrNoRows) { ... }` (same error wrapping via ErrMySQLQueryError stays
unchanged).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved needs-1-more-lgtm Indicates a PR needs 1 more LGTM. release-note-none Denotes a PR that doesn't merit a release note. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants