Skip to content

Commit a6cb39d

Browse files
committed
Handle expected close errors
Signed-off-by: Spike Curtis <spike@coder.com>
1 parent 3d408db commit a6cb39d

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

client.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,16 @@ func (r *remoteProcess) listen(ctx context.Context) {
217217

218218
r.closeErr = r.conn.Close(websocket.StatusNormalClosure, "normal closure")
219219
// If we were in r.conn.Read() we cancel the ctx, the websocket library closes
220-
// the websocket before we have a chance to. This is a normal closure.
221-
if r.closeErr != nil && strings.Contains(r.closeErr.Error(), "already wrote close") &&
222-
r.readErr != nil && strings.Contains(r.readErr.Error(), "context canceled") {
220+
// the websocket before we have a chance to. Unfortunately there is a race in the
221+
// the websocket library, where sometimes close frame has already been written before
222+
// we even call r.conn.Close(), and sometimes it gets written during our call to
223+
// r.conn.Close(), so we need to handle both those cases in examining the error that comes
224+
// back. This is a normal closure, so report nil for the error.
225+
readCtxCanceled := r.readErr != nil && strings.Contains(r.readErr.Error(), "context canceled")
226+
alreadyClosed := r.closeErr != nil &&
227+
(strings.Contains(r.closeErr.Error(), "already wrote close") ||
228+
strings.Contains(r.closeErr.Error(), "WebSocket closed"))
229+
if alreadyClosed && readCtxCanceled {
223230
r.closeErr = nil
224231
}
225232
close(r.done)

0 commit comments

Comments
 (0)