Skip to content

Commit e312a15

Browse files
committed
gracefully handle connection errors
1 parent 30eb624 commit e312a15

File tree

1 file changed

+44
-19
lines changed

1 file changed

+44
-19
lines changed

Diff for: commands/daemon/monitor.go

+44-19
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package daemon
1818
import (
1919
"fmt"
2020
"io"
21-
"log"
2221

2322
"github.com/arduino/arduino-cli/arduino/monitors"
2423
rpc "github.com/arduino/arduino-cli/rpc/monitor"
@@ -69,42 +68,68 @@ func (s *MonitorService) StreamingOpen(stream rpc.Monitor_StreamingOpenServer) e
6968
}
7069
}
7170

72-
// now we can stream the other messages and re-route to the monitor
71+
// we'll use these channels to communicate with the goroutines
72+
// handling the stream and the target respectively
73+
streamClosed := make(chan error)
74+
targetClosed := make(chan error)
75+
76+
// now we can read the other messages and re-route to the monitor...
7377
go func() {
7478
for {
7579
msg, err := stream.Recv()
7680
if err == io.EOF {
77-
// connection closed, exit
81+
// stream was closed
82+
streamClosed <- nil
7883
break
7984
}
8085

8186
if err != nil {
82-
// error, exit
83-
log.Fatal(err)
87+
// error reading from stream
88+
streamClosed <- err
8489
break
8590
}
8691

87-
mon.Write(msg.GetData())
92+
if _, err := mon.Write(msg.GetData()); err != nil {
93+
// error writing to target
94+
targetClosed <- err
95+
break
96+
}
8897
}
8998
}()
9099

91-
// read from the monitor and forward to the output stream
100+
// ...and read from the monitor and forward to the output stream
101+
go func() {
102+
buf := make([]byte, 8)
103+
for {
104+
n, err := mon.Read(buf)
105+
if err != nil {
106+
// error reading from target
107+
targetClosed <- err
108+
break
109+
}
92110

93-
buf := make([]byte, 8)
94-
for {
95-
n, err := mon.Read(buf)
96-
if err != nil {
97-
return err
98-
}
111+
if n == 0 {
112+
// target was closed
113+
targetClosed <- nil
114+
break
115+
}
99116

100-
if n == 0 {
101-
// port was closed
102-
return nil
117+
if err = stream.Send(&rpc.StreamingOpenResp{
118+
Data: buf[:n],
119+
}); err != nil {
120+
// error sending to stream
121+
streamClosed <- err
122+
break
123+
}
103124
}
125+
}()
104126

105-
if err = stream.Send(&rpc.StreamingOpenResp{
106-
Data: buf[:n],
107-
}); err != nil {
127+
for {
128+
select {
129+
case err := <-streamClosed:
130+
mon.Close()
131+
return err
132+
case err := <-targetClosed:
108133
return err
109134
}
110135
}

0 commit comments

Comments
 (0)