-
Notifications
You must be signed in to change notification settings - Fork 413
fix(output): route formatter errors through an injectable sink #290
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,12 +12,20 @@ import ( | |
| "github.com/larksuite/cli/internal/validate" | ||
| ) | ||
|
|
||
| // ErrorSink receives best-effort internal output formatting errors. | ||
| // Tests and embedders may override it to capture these messages. | ||
| var ErrorSink io.Writer = os.Stderr | ||
|
|
||
| func writeInternalError(format string, args ...interface{}) { | ||
| fmt.Fprintf(ErrorSink, format, args...) | ||
| } | ||
|
Comment on lines
+19
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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! |
||
|
|
||
| // PrintJson prints data as formatted JSON to w. | ||
| func PrintJson(w io.Writer, data interface{}) { | ||
| injectNotice(data) | ||
| b, err := json.MarshalIndent(data, "", " ") | ||
| if err != nil { | ||
| fmt.Fprintf(os.Stderr, "json marshal error: %v\n", err) | ||
| writeInternalError("json marshal error: %v\n", err) | ||
| return | ||
| } | ||
| fmt.Fprintln(w, string(b)) | ||
|
|
@@ -53,7 +61,7 @@ func PrintNdjson(w io.Writer, data interface{}) { | |
| emit := func(item interface{}) { | ||
| b, err := json.Marshal(item) | ||
| if err != nil { | ||
| fmt.Fprintf(os.Stderr, "ndjson marshal error: %v\n", err) | ||
| writeInternalError("ndjson marshal error: %v\n", err) | ||
| return | ||
| } | ||
| fmt.Fprintln(w, string(b)) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ErrorSinknot safe for concurrent accessThe exported
ErrorSinkvariable is an interface value read insidewriteInternalError(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 callingt.Parallel(), but the exported variable invites future callers to mutate it without synchronization. Consider using async/atomic.Pointer[io.Writer]or a small mutex-protected accessor to make this safe for concurrent use.