fix(output): route formatter errors through an injectable sink#290
fix(output): route formatter errors through an injectable sink#290OwenYWT wants to merge 1 commit intolarksuite:mainfrom
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughIntroduced a package-level, injectable Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Greptile SummaryThis PR replaces hardcoded Confidence Score: 5/5Safe to merge; all findings are minor style/best-practice suggestions that do not affect correctness. No P0 or P1 issues found. The change is a clean refactor with focused tests covering every modified error path. The two P2 notes (concurrency safety of the global var and the silent discard of fmt.Fprintf errors) do not affect correctness under current usage patterns. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[PrintJson] -->|marshal error| W[writeInternalError]
B[PrintNdjson] -->|marshal error| W
C[flushCSV] -->|flush error| W
W --> S{ErrorSink}
S -->|default| D[os.Stderr]
S -->|test override| E[bytes.Buffer]
S -->|embedder override| F[custom io.Writer]
Reviews (1): Last reviewed commit: "fix(output): route formatter errors thro..." | Re-trigger Greptile |
| var ErrorSink io.Writer = os.Stderr | ||
|
|
||
| func writeInternalError(format string, args ...interface{}) { | ||
| fmt.Fprintf(ErrorSink, format, args...) | ||
| } |
There was a problem hiding this comment.
ErrorSink not safe for concurrent access
The exported ErrorSink variable is an interface value read inside writeInternalError (which can be called from any goroutine processing output) and written by callers or test setup. Concurrent reads and writes of an interface variable are a data race in Go's memory model. The current tests avoid this by not calling t.Parallel(), but the exported variable invites future callers to mutate it without synchronization. Consider using a sync/atomic.Pointer[io.Writer] or a small mutex-protected accessor to make this safe for concurrent use.
| func writeInternalError(format string, args ...interface{}) { | ||
| fmt.Fprintf(ErrorSink, format, args...) | ||
| } |
There was a problem hiding this comment.
Silently ignored
ErrorSink write error
fmt.Fprintf returns (int, error) and the helper discards it. Given the "best-effort" framing this is intentional, but a brief //nolint or comment like // best-effort; ignore write errors would make it clear the discard is deliberate rather than accidental.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Summary
Stop output helpers from writing internal formatting failures directly to
os.Stderr.Changes
ErrorSinkfor best-effort formatter errorsErrorSinkTest Plan
GOCACHE=/tmp/go-build-cache GOMODCACHE=/tmp/go-mod-cache /opt/homebrew/opt/go/bin/go test ./cmd/... ./internal/outputSummary by CodeRabbit
Bug Fixes
Tests