From: Anderson A. Giacomolli Date: Wed, 11 Nov 2026 14:34:57 +0000 (-0300) Subject: Make intentional error discards explicit X-Git-Url: https://git.giacomolli.uk/onechat/commitdiff_plain/3aa065806f87d0876fbd7b05e5ded4aad380cc73?ds=sidebyside;hp=0979625154094df73577d6e2be2d0e9a0a87306c Make intentional error discards explicit Cancellation, removed-client cleanup, typing hints, and cancelled HTTP fake replies keep their nonfatal behavior with justified lint directives. Ordinary test response writes and final pipe cleanup check their errors. No blank assignment hides an unchecked error, and application shutdown and retry paths stay unchanged. Issue: 3cdc678 --- diff --git a/backup.go b/backup.go index 517b7c7..c03e633 100644 --- a/backup.go +++ b/backup.go @@ -37,7 +37,8 @@ func backup(ctx context.Context, path string, out io.Writer) (err error) { }() stop := context.AfterFunc(ctx, func() { - _ = conn.Close() + // Cancellation closes the socket only to interrupt pending I/O. + conn.Close() // nolint: errcheck }) defer stop() diff --git a/compactor_test.go b/compactor_test.go index 4934025..dcd9c33 100644 --- a/compactor_test.go +++ b/compactor_test.go @@ -133,7 +133,10 @@ func TestCompactorFailsWithoutALine(t *testing.T) { reply: func(w http.ResponseWriter, _ ModelFakeCall) { w.WriteHeader(http.StatusInternalServerError) - _, _ = io.WriteString(w, "down") + _, err := io.WriteString(w, "down") + if err != nil { + panic(err) + } }, want: "HTTP 500", }, diff --git a/daemon.go b/daemon.go index b6595c7..d6aa6aa 100644 --- a/daemon.go +++ b/daemon.go @@ -174,7 +174,9 @@ func (h *DaemonHub) remove(client *DaemonClient) { client.once.Do(func() { close(client.events) - _ = client.conn.Close() + // The client is removed already, so a close failure cannot + // restore it. + client.conn.Close() // nolint: errcheck }) } diff --git a/main.go b/main.go index 400538a..89eb839 100644 --- a/main.go +++ b/main.go @@ -12,7 +12,9 @@ import ( func main() { err := run() if err != nil { - fmt.Fprintln(os.Stderr, "onechat:", err) + // A failed error report cannot be reported through the same + // stream. + fmt.Fprintln(os.Stderr, "onechat:", err) // nolint: errcheck os.Exit(1) } } diff --git a/model_test.go b/model_test.go index 97be6e2..4045e9d 100644 --- a/model_test.go +++ b/model_test.go @@ -150,7 +150,10 @@ func TestClientRecordsEachCall(t *testing.T) { if call.number == 1 { w.WriteHeader(http.StatusTooManyRequests) - _, _ = io.WriteString(w, `{"detail": "slow down"}`) + _, err := io.WriteString(w, `{"detail": "slow down"}`) + if err != nil { + panic(err) + } return } diff --git a/subagent_run_test.go b/subagent_run_test.go index 30fcc78..708b515 100644 --- a/subagent_run_test.go +++ b/subagent_run_test.go @@ -182,7 +182,10 @@ func TestFullContextGivesAFailedReport(t *testing.T) { if subagentTestCall(call) { w.WriteHeader(http.StatusBadRequest) - _, _ = io.WriteString(w, subagentTestFullContext) + _, err := io.WriteString(w, subagentTestFullContext) + if err != nil { + panic(err) + } return } diff --git a/telegram.go b/telegram.go index e3e33c9..306f8f5 100644 --- a/telegram.go +++ b/telegram.go @@ -349,7 +349,8 @@ func (b *TelegramBot) next() (Event, bool) { // typing shows the typing action once. A failure is not logged, because the // next message or poll logs the state of the network. func (b *TelegramBot) typing(ctx context.Context) { - _ = b.api.SendTyping(ctx, b.owner) + // The next message or poll reports a network failure. + b.api.SendTyping(ctx, b.owner) // nolint: errcheck } // post sends event to the chat. A reply goes as rich messages of its Markdown, diff --git a/telegram_api_test.go b/telegram_api_test.go index 03d6c63..0da1395 100644 --- a/telegram_api_test.go +++ b/telegram_api_test.go @@ -150,7 +150,9 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { reply: func(w http.ResponseWriter) { conn, _, err := http.NewResponseController(w).Hijack() if err == nil { - _ = conn.Close() + // This forced disconnect has no + // response or retry after close. + conn.Close() // nolint: errcheck } }, retry: true, @@ -161,7 +163,10 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { reply: func(w http.ResponseWriter) { w.WriteHeader(http.StatusTooManyRequests) - _, _ = io.WriteString(w, `{"ok":false,"error_code":429,"description":"Too Many Requests: retry after 3","parameters":{"retry_after":3}}`) + _, err := io.WriteString(w, `{"ok":false,"error_code":429,"description":"Too Many Requests: retry after 3","parameters":{"retry_after":3}}`) + if err != nil { + panic(err) + } }, retry: true, wait: 3 * time.Second, @@ -172,7 +177,10 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { reply: func(w http.ResponseWriter) { w.WriteHeader(http.StatusBadGateway) - _, _ = io.WriteString(w, "bad gateway") + _, err := io.WriteString(w, "bad gateway") + if err != nil { + panic(err) + } }, retry: true, errorText: "502 Bad Gateway", @@ -182,7 +190,10 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { reply: func(w http.ResponseWriter) { w.WriteHeader(http.StatusUnauthorized) - _, _ = io.WriteString(w, `{"ok":false,"error_code":401,"description":"Unauthorized: bot`+telegramTestToken+`"}`) + _, err := io.WriteString(w, `{"ok":false,"error_code":401,"description":"Unauthorized: bot`+telegramTestToken+`"}`) + if err != nil { + panic(err) + } }, retry: false, errorText: "Unauthorized: botTOKEN", @@ -192,7 +203,10 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { reply: func(w http.ResponseWriter) { w.WriteHeader(http.StatusBadRequest) - _, _ = io.WriteString(w, `{"ok":false,"error_code":400,"description":"Bad Request: can't parse"}`) + _, err := io.WriteString(w, `{"ok":false,"error_code":400,"description":"Bad Request: can't parse"}`) + if err != nil { + panic(err) + } }, retry: false, rejected: true, @@ -203,7 +217,10 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { reply: func(w http.ResponseWriter) { w.WriteHeader(http.StatusNotFound) - _, _ = io.WriteString(w, `{"ok":false,"error_code":404,"description":"Not Found"}`) + _, err := io.WriteString(w, `{"ok":false,"error_code":404,"description":"Not Found"}`) + if err != nil { + panic(err) + } }, retry: false, rejected: true, @@ -214,7 +231,10 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { reply: func(w http.ResponseWriter) { w.WriteHeader(http.StatusNotFound) - _, _ = io.WriteString(w, "not found") + _, err := io.WriteString(w, "not found") + if err != nil { + panic(err) + } }, retry: false, errorText: "404 Not Found", @@ -222,7 +242,10 @@ func TestBotErrorsDoNotHoldTheToken(t *testing.T) { { name: "broken answer is retried", reply: func(w http.ResponseWriter) { - _, _ = io.WriteString(w, `{"ok":`) + _, err := io.WriteString(w, `{"ok":`) + if err != nil { + panic(err) + } }, retry: true, errorText: "invalid JSON", diff --git a/telegram_fake_helper_test.go b/telegram_fake_helper_test.go index 6ca755e..5ed4e2d 100644 --- a/telegram_fake_helper_test.go +++ b/telegram_fake_helper_test.go @@ -101,7 +101,9 @@ func (f *TelegramFake) serve(w http.ResponseWriter, r *http.Request) { return } - _, _ = w.Write(data) + // The client can cancel a media request before this reply is + // written. + w.Write(data) // nolint: errcheck return } @@ -188,7 +190,9 @@ func (f *TelegramFake) serve(w http.ResponseWriter, r *http.Request) { wait = 1 } - _, _ = fmt.Fprintf(w, `{"ok":false,"error_code":%d,"description":%q,"parameters":{"retry_after":%d}}`, status, description, wait) + // A test can cancel the request after the handler selects its + // reply. + fmt.Fprintf(w, `{"ok":false,"error_code":%d,"description":%q,"parameters":{"retry_after":%d}}`, status, description, wait) // nolint: errcheck return } @@ -197,7 +201,8 @@ func (f *TelegramFake) serve(w http.ResponseWriter, r *http.Request) { f.record(call) if method == "getFile" { - _ = json.NewEncoder(w).Encode(map[string]any{ + // A cancelled client does not need a response body. + json.NewEncoder(w).Encode(map[string]any{ // nolint: errcheck "ok": true, "result": map[string]any{"file_path": params["file_id"]}, }) @@ -206,7 +211,9 @@ func (f *TelegramFake) serve(w http.ResponseWriter, r *http.Request) { } if method != "getUpdates" { - _, _ = io.WriteString(w, `{"ok":true,"result":true}`) + // A cancelled client does not need a response body. + io.WriteString(w, `{"ok":true,"result":true}`) // nolint: errcheck + return } @@ -222,7 +229,8 @@ func (f *TelegramFake) serve(w http.ResponseWriter, r *http.Request) { updates = f.from(offset) } - _ = json.NewEncoder(w).Encode(map[string]any{ + // A cancelled client does not need a response body. + json.NewEncoder(w).Encode(map[string]any{ // nolint: errcheck "ok": true, "result": updates, }) diff --git a/terminal_client_helper_test.go b/terminal_client_helper_test.go index 8dbc646..5018e89 100644 --- a/terminal_client_helper_test.go +++ b/terminal_client_helper_test.go @@ -70,7 +70,7 @@ func terminalStartTestClient(t *testing.T, socket string) *TerminalTestClient { }() t.Cleanup(func() { - _ = writer.Close() + require.NoError(t, writer.Close()) }) return client