From 2d7dd7310613f02010317d3db5b29edbf656f2fe Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Wed, 11 Mar 2026 09:48:07 +0000 Subject: [PATCH] chore(httpapi): do not log context.Canceled as error (#22933) A cursory glance at Grafana for error-level logs showed that the following log line was appearing regularly: ``` 2026-03-11 05:17:59.169 [erro] coderd: failed to heartbeat ping trace=xxx span=xxx request_id=xxx ... error= failed to ping: github.com/coder/coder/v2/coderd/httpapi.pingWithTimeout /home/runner/work/coder/coder/coderd/httpapi/websocket.go:46 - failed to ping: failed to wait for pong: context canceled ``` This seems to be an "expected" error when the parent context is canceled so doesn't make sense to log at level ERROR. NOTE: I also saw this a bit and wonder if it also deserves similar treatment: ``` 2026-03-11 05:10:53.229 [erro] coderd.inbox_notifications_watcher: failed to heartbeat ping trace=xxx span=xxx request_id=xxx ... error= failed to ping: github.com/coder/coder/v2/coderd/httpapi.pingWithTimeout /home/runner/work/coder/coder/coderd/httpapi/websocket.go:46 - failed to ping: failed to write control frame opPing: use of closed network connection ``` --- coderd/httpapi/websocket.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/coderd/httpapi/websocket.go b/coderd/httpapi/websocket.go index ea9e505146..b0c7e456b5 100644 --- a/coderd/httpapi/websocket.go +++ b/coderd/httpapi/websocket.go @@ -27,8 +27,11 @@ func HeartbeatClose(ctx context.Context, logger slog.Logger, exit func(), conn * } err := pingWithTimeout(ctx, conn, HeartbeatInterval) if err != nil { - // context.DeadlineExceeded is expected when the client disconnects without sending a close frame - if !errors.Is(err, context.DeadlineExceeded) { + // context.DeadlineExceeded is expected when the client disconnects without sending a close frame. + // context.Canceled is expected when the request context is canceled. + if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) { + logger.Debug(ctx, "heartbeat ping stopped", slog.Error(err)) + } else { logger.Error(ctx, "failed to heartbeat ping", slog.Error(err)) } _ = conn.Close(websocket.StatusGoingAway, "Ping failed")