]> git.giacomolli.uk - onechat/commitdiff
Make intentional error discards explicit
authorAnderson A. Giacomolli <redacted>
Wed, 11 Nov 2026 14:34:57 +0000 (11:34 -0300)
committerAnderson A. Giacomolli <redacted>
Wed, 11 Nov 2026 14:34:57 +0000 (11:34 -0300)
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

backup.go
compactor_test.go
daemon.go
main.go
model_test.go
subagent_run_test.go
telegram.go
telegram_api_test.go
telegram_fake_helper_test.go
terminal_client_helper_test.go

index 517b7c7af5eeeba953aff24e4d90830dd387bf22..c03e633df77666e161d9c636348bfb44977d0bee 100644 (file)
--- 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()
index 493402551e6d8bf7fa8697b96d3ef27476d815c1..dcd9c3379edc5d984707c26c815f106923ef2349 100644 (file)
@@ -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",
                },
index b6595c7624a12ef316f0c01a892584791a5b4637..d6aa6aaa8cf247cb2ec4a613fab3344cf0b7eaaf 100644 (file)
--- 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 400538a39a3193be98a7f54d3060ce459a9bc970..89eb839d1f970eba36047c3a7cc4f395749576fe 100644 (file)
--- 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)
        }
 }
index 97be6e241a0d46044ba7ddaba4fee10c933b26a8..4045e9deade3f5b2db80e8e68de2f1dcebf40626 100644 (file)
@@ -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
                }
index 30fcc78fdae947d4f724443ed7aa36590e443dfb..708b515745074ff889391970eda186b32cf6ed71 100644 (file)
@@ -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
                }
index e3e33c913734b6901f02808f7a9d004fd2aa6f9f..306f8f5ab293a438da20411250b92ba21c4334d2 100644 (file)
@@ -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,
index 03d6c63b6b7691e04146c694e676e8c9a3b0ec15..0da139590f312a1014863ce98a9411ed6806495e 100644 (file)
@@ -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, "<html>bad gateway</html>")
+                               _, err := io.WriteString(w, "<html>bad gateway</html>")
+                               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, "<html>not found</html>")
+                               _, err := io.WriteString(w, "<html>not found</html>")
+                               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",
index 6ca755e6545383cefe0b4a3d4066aea784587283..5ed4e2d43d60137938f45ee792f1a5f1a13d1c24 100644 (file)
@@ -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,
        })
index 8dbc646cce516ffbbc57dbf47d99ea5153a8f236..5018e89684d3fa4e1d5bf929a1b8b9286cf5276e 100644 (file)
@@ -70,7 +70,7 @@ func terminalStartTestClient(t *testing.T, socket string) *TerminalTestClient {
        }()
 
        t.Cleanup(func() {
-               _ = writer.Close()
+               require.NoError(t, writer.Close())
        })
 
        return client