@@ -1038,12 +1038,14 @@ func (a *agent) handleReconnectingPTY(ctx context.Context, logger slog.Logger, m
1038
1038
// 1. The timeout completed.
1039
1039
// 2. The parent context was canceled.
1040
1040
<- ctx .Done ()
1041
+ logger .Debug (ctx ,"context done" ,slog .Error (ctx .Err ()))
1041
1042
_ = process .Kill ()
1042
1043
}()
1043
1044
go func () {
1044
1045
// If the process dies randomly, we should
1045
1046
// close the pty.
1046
- _ = process .Wait ()
1047
+ err := process .Wait ()
1048
+ logger .Debug (ctx ,"process exited" ,slog .Error (err ))
1047
1049
rpty .Close ()
1048
1050
}()
1049
1051
if err = a .trackConnGoroutine (func () {
@@ -1052,6 +1054,8 @@ func (a *agent) handleReconnectingPTY(ctx context.Context, logger slog.Logger, m
1052
1054
read ,err := rpty .ptty .OutputReader ().Read (buffer )
1053
1055
if err != nil {
1054
1056
// When the PTY is closed, this is triggered.
1057
+ // Error is typically a benign EOF, so only log for debugging.
1058
+ logger .Debug (ctx ,"PTY output read error" ,slog .Error (err ))
1055
1059
break
1056
1060
}
1057
1061
part := buffer [:read ]
@@ -1063,8 +1067,14 @@ func (a *agent) handleReconnectingPTY(ctx context.Context, logger slog.Logger, m
1063
1067
break
1064
1068
}
1065
1069
rpty .activeConnsMutex .Lock ()
1066
- for _ ,conn := range rpty .activeConns {
1067
- _ ,_ = conn .Write (part )
1070
+ for cid ,conn := range rpty .activeConns {
1071
+ _ ,err = conn .Write (part )
1072
+ logger .Debug (ctx ,
1073
+ "wrote to active conn" ,
1074
+ slog .F ("other_conn_id" ,cid ),
1075
+ slog .F ("data" ,part ),
1076
+ slog .Error (err ),
1077
+ )
1068
1078
}
1069
1079
rpty .activeConnsMutex .Unlock ()
1070
1080
}