Skip to content

Fix 137 golangci lint errors#138

Merged
AlexStocks merged 4 commits intodubbogo:masterfrom
LEILEI0628:fix-137-golangci-lint-errors
Feb 2, 2026
Merged

Fix 137 golangci lint errors#138
AlexStocks merged 4 commits intodubbogo:masterfrom
LEILEI0628:fix-137-golangci-lint-errors

Conversation

@LEILEI0628
Copy link
Copy Markdown
Contributor

@LEILEI0628 LEILEI0628 commented Jan 30, 2026

What this PR does:
This PR resolves code quality issues identified by golangci-lint to improve code maintainability and reliability. The changes include:

  1. Resolve 26 errcheck linter errors: Fix all unchecked error returns throughout the codebase

    • Fix implicit error ignores in tests
    • Add fail-fast for test prerequisites
    • Explicitly ignore cleanup errors with rationale comments
    • Handle non-critical log print errors
  2. Resolve additional golangci-lint issues: Simplify code patterns and improve readability

    • Simplify for-select patterns to direct channel operations
    • Replace if-else chains with switch statements
    • Eliminate redundant boolean expressions and loops
    • Fix Yoda conditions to natural comparison order
    • Remove unnecessary select statements
    • Clean up dead code and unused return statements

All changes are refactoring only with no functional modifications. All tests pass.
Which issue(s) this PR fixes:

Fixes #137

Special notes for your reviewer:

These are purely code quality improvements identified by golangci-lint. No functional changes are introduced. Key areas of improvement:

  • Error handling is now explicit throughout the codebase
  • Code patterns are simplified for better readability
  • Dead code and redundant logic removed

Does this PR introduce a user-facing change?:

NONE

Summary by CodeRabbit

  • New Features

    • Queue operations now return errors for clearer failure reporting.
    • New string utilities: deep nil-check, regex-based split, and zero-copy string→[]byte conversion.
  • Bug Fixes

    • Corrected grammar in a buffer error message.
  • Improvements

    • Simplified timer, worker, and event handling with safer enqueue/loop semantics.
    • Unified error-ignoring for non-critical prints and resource closes.
    • Tests updated to handle new error returns and simplified channel/timer patterns.

✏️ Tip: You can customize this high-level summary in your review settings.

yaolei_cao added 2 commits January 19, 2026 18:51
  - Fix implicit error ignores in tests
  - Add fail-fast for test prerequisites
  - Explicit ignore cleanup errors + add rationale comments
  - Handle non-critical log print errors
- Simplify for-select patterns to direct channel operations
- Replace if-else chains with switch statements
- Eliminate redundant boolean expressions and loops
- Fix Yoda conditions to natural comparison order
- Remove unnecessary select statements
- Clean up dead code and unused return statements

No functional changes. All tests pass.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jan 30, 2026

📝 Walkthrough

Walkthrough

Queue API gained error returns; timer enqueueing was added; ZK event handling and several channel/select patterns were refactored; many tests updated to check or explicitly ignore returned errors; new gxstrings utilities (IsNil, RegSplit, Slice) were added.

Changes

Cohort / File(s) Summary
Queue API & tests
container/queue/queue.go, container/queue/queue_test.go
Put(...interface{}) now returns error; Poll(...) now returns (interface{}, error). Tests updated to capture/assert/ignore these errors.
Timer internals & enqueueing
time/timer.go
Added enqueueTimerAction (non-blocking enqueue with error); Add/Delete/Reset use it and now return errors when enqueue fails; action dispatch replaced by a direct switch.
ZK event loop refactor
database/kv/zk/client.go, database/kv/zk/client_test.go
HandleZkEvent rewritten to range over z.Session with explicit state switch and listener dispatch; tests now explicitly ignore returned errors from Stop.
Channel/select simplifications & worker
container/chan/unbounded_chan_test.go, sync/base_worker_pool.go, time/sleep_test.go
Single-case select usages removed; receives/sends made direct; worker loops use range over channels; timer tests simplified to plain loops.
Bytes, pool, buffer tests
bytes/buffer.go, bytes/buffer_test.go, bytes/bytes_pool.go
Fixed error message capitalization; call return values are checked/ignored to satisfy errcheck; make([]byte, size, size) simplified to make([]byte, size).
Etcd keep-alive & cleanup
database/kv/etcd/v3/client.go, database/kv/etcd/v3/client_test.go
clean() and keep-alive failure paths now ignore Close/Revoke errors and ensure keep-alive failures return an error; tests updated to check CleanKV error.
Logging: ignore print errors & encoder switch
log/color.go, log/pretty.go, log/logger/logger.go
Fprintf/pretty-print errors are discarded with comments; encoder selection refactored to a switch on c.ZapConfig.Encoding.
gxstrings additions & tests
strings/strings.go, strings/slice.go, strings/strings_test.go
Added IsNil(i interface{}) bool, RegSplit(text, regexSplit) []string, and Slice(s string) []byte (unsafe, documented); tests added for IsNil.
Math/big refinements & tests
math/big/decimal.go, math/big/helper.go, math/big/integer_test.go
Adjusted loop conditions for trailing-zero detection; replaced some if-else with switch; tests now check FromString errors and clearer condition logic.
Net & runtime small edits
net/net.go, net/net_test.go, runtime/sys.go
Reordered Yoda comparisons for readability; some Close()/defer Close() errors explicitly ignored.
Misc tests & minor refactors
database/kv/etcd/v3/client_test.go, other test files
Various tests updated to capture or explicitly ignore new/previously-unchecked return values; small readability refactors across files.

Sequence Diagram(s)

sequenceDiagram
participant ZkConn
participant SessionCh as z.Session
participant Handler as HandleZkEvent
participant Listeners

ZkConn->>SessionCh: emit Event {State, Path, Type}
SessionCh->>Handler: receive Event
Handler->>Handler: switch on Event.State
alt StateConnected
    Handler->>Listeners: dispatch event to path-matched listeners
else StateHasSession / StateConnecting
    Handler->>Handler: set internal state, prepare reconnect channel
else StateExpired
    Handler->>Handler: update state, possibly reconnect
end
Handler->>ZkConn: update internal state & continue
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I nibble at selects and hop to range,
I check a few errors and shrug at some, not strange.
Timers line up, queues politely return "err",
New string tricks — unsafe slice — I prefer.
A happy hop for tests made tidy, quick, and spare.

🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The pull request introduces two new public functions (IsNil and RegSplit in strings package, and Slice in strings/slice.go) that are not mentioned in issue #137's scope, which focused solely on fixing linter errors. Remove the new IsNil, RegSplit, and Slice functions, or move them to a separate PR focused on adding new functionality. The current PR should remain limited to fixing the 51 linter issues from #137.
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Fix 137 golangci lint errors' directly and clearly summarizes the main change—resolving linter issues from issue #137 without functional changes.
Linked Issues check ✅ Passed The pull request successfully addresses all coding-related objectives from issue #137: resolving 26 errcheck errors by checking/ignoring returns, fixing 22 staticcheck issues through refactoring, removing 3 unused declarations, and improving code quality without introducing functional changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@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

🤖 Fix all issues with AI agents
In `@time/timer.go`:
- Around line 512-515: The direct blocking send to w.timerQ.In() (e.g., the line
creating &timerNodeAction{...} in AddTimer/deleteTimer/resetTimer) can deadlock
when called from the timer wheel goroutine because UnboundedChan.In() is bounded
and its internal pump can block; change these direct sends to a non-blocking
enqueue with error handling (use a select with default or an enqueue helper that
returns an error) so attempts to send a timerNodeAction to w.timerQ are either
queued or fail fast with a clear error/metric instead of blocking; update the
callers (AddTimer, deleteTimer, resetTimer) to handle the enqueue error
(propagate or log) and ensure the timer wheel goroutine never performs a
blocking send to timerQ.In().
🧹 Nitpick comments (4)
database/kv/etcd/v3/client.go (1)

176-179: Consider logging Close() failures instead of silently ignoring them.
Ignoring the error hides useful signals when resource cleanup fails.

♻️ Suggested change
 	// close raw client
 	// cleanup prioritizes resource release
-	_ = c.rawClient.Close()
+	if err := c.rawClient.Close(); err != nil {
+		log.Printf("etcd client close error: %v", err)
+	}
runtime/sys.go (1)

200-203: Consider a simpler form for ignoring the close error.

The anonymous function wrapper is more verbose than necessary. A direct blank identifier assignment achieves the same lint fix with less code.

Proposed simplification
-	defer func() {
-		// file is read-only
-		_ = f.Close()
-	}()
+	defer func() { _ = f.Close() }() // file is read-only, error non-critical

Or even simpler if linter permits:

defer f.Close() //nolint:errcheck // file is read-only
database/kv/zk/client_test.go (1)

81-82: Prefer asserting Stop() errors in tests instead of discarding.

This keeps cleanup failures visible.

♻️ Suggested adjustment
-	_ = tc.Stop()
+	assert.NoError(t, tc.Stop())

Also applies to: 129-130

container/queue/queue_test.go (1)

156-157: Consider asserting the error behavior for completeness.

The test verifies the queue length but ignores the error return. If the intended behavior is that empty Put() is a valid no-op, asserting err == nil would document that. If it should return an error, that should be tested instead.

💡 Suggestion to verify error behavior
 	// testing empty parameters behavior
-	_ = q.Put()
+	err := q.Put()
+	assert.Nil(t, err) // or assert an expected error if empty Put should fail

Comment thread time/timer.go Outdated
@AlexStocks
Copy link
Copy Markdown
Collaborator

@LEILEI0628 看下 coderabbit 的 code review 的结果哈

- Prevent potential deadlock in timer wheel
  - Replace blocking channel sends with non-blocking select pattern
  - Add enqueueTimerAction helper method for fail-fast behavior
  - Update AddTimer, deleteTimer, and resetTimer to handle enqueue errors
- Add missing docstrings for strings package
  - Add docstring for IsNil with deep nil checking explanation
  - Add docstring for RegSplit with parameters and usage example
  - Add comprehensive docstring for Slice with unsafe operation warnings
Docstring coverage increased from 25% to 100% (4/4 functions).
No functional changes. All tests pass.
Copy link
Copy Markdown

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
strings/strings.go (1)

30-40: ⚠️ Potential issue | 🔴 Critical

IsNil will panic for non-nilable types.

reflect.Value.IsNil() panics if the value's Kind is not Chan, Func, Interface, Map, Pointer, Slice, or UnsafePointer. Calling IsNil(42) or IsNil("hello") will cause a runtime panic.

🐛 Proposed fix: Check Kind before calling IsNil
 func IsNil(i interface{}) bool {
 	if i == nil {
 		return true
 	}
 
-	if reflect.ValueOf(i).IsNil() {
-		return true
+	v := reflect.ValueOf(i)
+	switch v.Kind() {
+	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer, reflect.Slice, reflect.UnsafePointer:
+		return v.IsNil()
+	default:
+		return false
 	}
-
-	return false
 }
🤖 Fix all issues with AI agents
In `@time/timer.go`:
- Around line 467-480: enqueueTimerAction now can return an error when the queue
is full and that error bubbles up into APIs that assume NewTimer/AddTimer always
succeed (e.g. After, Sleep, Tick, AfterFunc, TickFunc), which can cause nil
pointer panics or dropped work; update those convenience methods to detect a
nil/new-timer error and handle enqueue failures gracefully (choose one strategy
consistently: return nil channels or error-returning variants, or implement a
small retry/backoff loop inside AddTimer/NewTimer before returning nil), e.g.
modify After, Sleep, Tick, AfterFunc, TickFunc to check the result of
NewTimer/AddTimer and either return nil or an error to callers instead of
dereferencing nil timers, and document the chosen behavior. Ensure references:
enqueueTimerAction, AddTimer, NewTimer, After, Sleep, Tick, AfterFunc, TickFunc
are updated accordingly.
🧹 Nitpick comments (1)
strings/slice.go (1)

39-42: Consider documenting empty string behavior.

Per Go's documentation, unsafe.StringData has unspecified behavior for empty strings, which could return nil. This would result in a nil slice rather than an empty slice ([]byte(nil) vs []byte{}), potentially causing subtle issues for callers checking slice == nil.

Option 1: Document the behavior
 // Use this function only when you need read-only access to string bytes
 // with zero allocation, and you understand the safety implications.
+//
+// Note: For empty strings, the result may be a nil slice rather than
+// an empty slice due to unsafe.StringData's unspecified behavior.
 func Slice(s string) []byte {
Option 2: Handle empty string explicitly
 func Slice(s string) []byte {
+	if len(s) == 0 {
+		return nil
+	}
 	ptr := unsafe.StringData(s)
 	return unsafe.Slice((*byte)(ptr), len(s))
 }

Comment thread time/timer.go
- Fix IsNil panic for non-nilable types
  - Check reflect.Kind before calling IsNil to prevent panic
  - Add comprehensive test coverage for all type categories
- Prevent timer wheel convenience API panics
  - Add nil checks in After, Sleep, AfterFunc, and Tick methods
  - Return nil/exit early when timer creation fails under load
  - Remove outdated commented code in After method
- Add missing docstrings for strings package
  - Add docstring for RegSplit with parameters and usage example
  - Add comprehensive docstring for Slice with unsafe operation warnings
Copy link
Copy Markdown

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
time/timer.go (1)

653-663: ⚠️ Potential issue | 🟡 Minor

Tick doc claims d <= 0 returns nil, but the method doesn't explicitly check it.

The method delegates to NewTicker(d), which also lacks an explicit d <= 0 guard. Either add the guard at the method level or adjust the doc comment to match the actual enforcement.

✏️ Comment-only fix (no behavior change)
-// Unlike NewTicker, Tick will return nil if d <= 0 or if the ticker cannot be created.
+// Unlike NewTicker, Tick will return nil if the ticker cannot be created.
🧹 Nitpick comments (1)
time/timer.go (1)

467-480: Use a sentinel error for queue-full to enable errors.Is checks.
Returning a new error value each time makes it harder for callers to classify failures programmatically.

🔧 Suggested tweak
 var ErrTimeChannelClosed = errors.New("timer channel closed")
+var ErrTimerQueueFull = errors.New("timer queue is full, cannot enqueue action without blocking")
 	default:
-		return errors.New("timer queue is full, cannot enqueue action without blocking")
+		return ErrTimerQueueFull
 	}

@AlexStocks AlexStocks merged commit 83e0fee into dubbogo:master Feb 2, 2026
3 checks passed
@Alanxtl Alanxtl linked an issue Feb 13, 2026 that may be closed by this pull request
1 task
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.

golangci-lint issue [BUG] gost lint fail

2 participants