summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
inline | side by side (from parent 1:
0979625)
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
}()
stop := context.AfterFunc(ctx, func() {
}()
stop := context.AfterFunc(ctx, func() {
+ // Cancellation closes the socket only to interrupt pending I/O.
+ conn.Close() // nolint: errcheck
reply: func(w http.ResponseWriter, _ ModelFakeCall) {
w.WriteHeader(http.StatusInternalServerError)
reply: func(w http.ResponseWriter, _ ModelFakeCall) {
w.WriteHeader(http.StatusInternalServerError)
- _, _ = io.WriteString(w, "down")
+ _, err := io.WriteString(w, "down")
+ if err != nil {
+ panic(err)
+ }
client.once.Do(func() {
close(client.events)
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
func main() {
err := run()
if err != nil {
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
if call.number == 1 {
w.WriteHeader(http.StatusTooManyRequests)
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)
+ }
if subagentTestCall(call) {
w.WriteHeader(http.StatusBadRequest)
if subagentTestCall(call) {
w.WriteHeader(http.StatusBadRequest)
- _, _ = io.WriteString(w, subagentTestFullContext)
+ _, err := io.WriteString(w, subagentTestFullContext)
+ if err != nil {
+ panic(err)
+ }
// 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) {
// 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,
}
// post sends event to the chat. A reply goes as rich messages of its Markdown,
reply: func(w http.ResponseWriter) {
conn, _, err := http.NewResponseController(w).Hijack()
if err == nil {
reply: func(w http.ResponseWriter) {
conn, _, err := http.NewResponseController(w).Hijack()
if err == nil {
+ // This forced disconnect has no
+ // response or retry after close.
+ conn.Close() // nolint: errcheck
reply: func(w http.ResponseWriter) {
w.WriteHeader(http.StatusTooManyRequests)
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,
},
retry: true,
wait: 3 * time.Second,
reply: func(w http.ResponseWriter) {
w.WriteHeader(http.StatusBadGateway)
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",
},
retry: true,
errorText: "502 Bad Gateway",
reply: func(w http.ResponseWriter) {
w.WriteHeader(http.StatusUnauthorized)
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",
},
retry: false,
errorText: "Unauthorized: botTOKEN",
reply: func(w http.ResponseWriter) {
w.WriteHeader(http.StatusBadRequest)
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,
},
retry: false,
rejected: true,
reply: func(w http.ResponseWriter) {
w.WriteHeader(http.StatusNotFound)
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,
},
retry: false,
rejected: true,
reply: func(w http.ResponseWriter) {
w.WriteHeader(http.StatusNotFound)
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",
},
retry: false,
errorText: "404 Not Found",
{
name: "broken answer is retried",
reply: func(w http.ResponseWriter) {
{
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",
},
retry: true,
errorText: "invalid JSON",
+ // The client can cancel a media request before this reply is
+ // written.
+ w.Write(data) // nolint: errcheck
- _, _ = 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
f.record(call)
if method == "getFile" {
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"]},
})
"ok": true,
"result": map[string]any{"file_path": params["file_id"]},
})
}
if method != "getUpdates" {
}
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
+
updates = f.from(offset)
}
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,
})
"ok": true,
"result": updates,
})
+ require.NoError(t, writer.Close())