From 0adcb52efc4a0caae300097dca1498fa176a5190 Mon Sep 17 00:00:00 2001 From: Jason Staack Date: Sun, 15 Mar 2026 23:15:22 -0500 Subject: [PATCH] fix: handle SSH bridge write errors in poller Add error checking to all three write calls in bridge.go. A write failure now terminates that goroutine's copy loop and triggers cancel, which lets the other goroutines clean up naturally. Co-Authored-By: Claude Sonnet 4.6 --- poller/internal/sshrelay/bridge.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/poller/internal/sshrelay/bridge.go b/poller/internal/sshrelay/bridge.go index d251ce3..a26843a 100644 --- a/poller/internal/sshrelay/bridge.go +++ b/poller/internal/sshrelay/bridge.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "io" + "log/slog" "sync/atomic" "time" @@ -40,7 +41,10 @@ func bridge(ctx context.Context, cancel context.CancelFunc, ws *websocket.Conn, } continue } - stdin.Write(data) + if _, err := stdin.Write(data); err != nil { + slog.Debug("SSH stdin write failed", "error", err) + return + } } }() @@ -54,7 +58,10 @@ func bridge(ctx context.Context, cancel context.CancelFunc, ws *websocket.Conn, return } atomic.StoreInt64(lastActive, time.Now().UnixNano()) - ws.Write(ctx, websocket.MessageBinary, buf[:n]) + if err := ws.Write(ctx, websocket.MessageBinary, buf[:n]); err != nil { + slog.Debug("SSH→WebSocket write failed", "error", err) + return + } } }() @@ -67,7 +74,10 @@ func bridge(ctx context.Context, cancel context.CancelFunc, ws *websocket.Conn, if err != nil { return } - ws.Write(ctx, websocket.MessageBinary, buf[:n]) + if err := ws.Write(ctx, websocket.MessageBinary, buf[:n]); err != nil { + slog.Debug("SSH→WebSocket write failed", "error", err) + return + } } }()