Skip to content

Commit 40e720d

Browse files
authored
fix(muxer): Return better error message when the peer closes the connection (#1038)
* fix(muxer): Wrap io.EOF errors with friendly message when peer closes connection Signed-off-by: Akhil Repala <[email protected]> * fix(muxer): wrap EOF using ConnectionClosedError and update downstream checks Signed-off-by: Akhil Repala <[email protected]> --------- Signed-off-by: Akhil Repala <[email protected]>
1 parent c284922 commit 40e720d

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

connection.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,10 @@ func (c *Connection) setupConnection() error {
285285
if !ok {
286286
return
287287
}
288-
if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
289-
// Return a bare io.EOF error if error is EOF/ErrUnexpectedEOF
290-
c.errorChan <- io.EOF
288+
var connErr *muxer.ConnectionClosedError
289+
if errors.As(err, &connErr) {
290+
// Pass through ConnectionClosedError from muxer
291+
c.errorChan <- err
291292
} else {
292293
// Wrap error message to denote it comes from the muxer
293294
c.errorChan <- fmt.Errorf("muxer error: %w", err)
@@ -354,7 +355,7 @@ func (c *Connection) setupConnection() error {
354355
select {
355356
case <-c.doneChan:
356357
// Return an error if we're shutting down
357-
return io.EOF
358+
return fmt.Errorf("connection shutdown initiated: %w", io.EOF)
358359
case err := <-c.protoErrorChan:
359360
// Shutdown the connection and return the error
360361
c.Close()

muxer/muxer.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,19 @@ type Muxer struct {
6969
onceStop sync.Once
7070
}
7171

72+
type ConnectionClosedError struct {
73+
Context string
74+
Err error
75+
}
76+
77+
func (e *ConnectionClosedError) Error() string {
78+
return fmt.Sprintf("peer closed the connection while %s: %v", e.Context, e.Err)
79+
}
80+
81+
func (e *ConnectionClosedError) Unwrap() error {
82+
return e.Err
83+
}
84+
7285
// New creates a new Muxer object and starts the read loop
7386
func New(conn net.Conn) *Muxer {
7487
m := &Muxer{
@@ -287,7 +300,11 @@ func (m *Muxer) readLoop() {
287300
if errors.Is(err, io.ErrClosedPipe) {
288301
err = io.EOF
289302
}
290-
m.sendError(err)
303+
if errors.Is(err, io.EOF) {
304+
m.sendError(&ConnectionClosedError{Context: "reading header", Err: err})
305+
} else {
306+
m.sendError(err)
307+
}
291308
return
292309
}
293310
msg := &Segment{
@@ -300,7 +317,11 @@ func (m *Muxer) readLoop() {
300317
if errors.Is(err, io.ErrClosedPipe) {
301318
err = io.EOF
302319
}
303-
m.sendError(err)
320+
if errors.Is(err, io.EOF) {
321+
m.sendError(&ConnectionClosedError{Context: "reading payload", Err: err})
322+
} else {
323+
m.sendError(err)
324+
}
304325
return
305326
}
306327
// Check for message from initiator when we're not configured as a responder

0 commit comments

Comments
 (0)