Skip to content

Commit d532611

Browse files
Fix panic on send to closed event channel in Go SDK
Protect dispatchEvent with a recover guard so that a notification arriving after Disconnect does not crash the process. Also wrap the channel close in sync.Once so Disconnect is safe to call more than once. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent e320690 commit d532611

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

go/session.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ type Session struct {
6767

6868
// eventCh serializes user event handler dispatch. dispatchEvent enqueues;
6969
// a single goroutine (processEvents) dequeues and invokes handlers in FIFO order.
70-
eventCh chan SessionEvent
70+
eventCh chan SessionEvent
71+
closeOnce sync.Once // guards eventCh close so Disconnect is safe to call more than once
7172

7273
// RPC provides typed session-scoped RPC methods.
7374
RPC *rpc.SessionRpc
@@ -451,7 +452,15 @@ func (s *Session) handleHooksInvoke(hookType string, rawInput json.RawMessage) (
451452
// serial, FIFO dispatch without blocking the read loop.
452453
func (s *Session) dispatchEvent(event SessionEvent) {
453454
go s.handleBroadcastEvent(event)
454-
s.eventCh <- event
455+
456+
// Send to the event channel in a closure with a recover guard.
457+
// Disconnect closes eventCh, and in Go sending on a closed channel
458+
// panics — there is no non-panicking send primitive. We only want
459+
// to suppress that specific panic; other panics are not expected here.
460+
func() {
461+
defer func() { recover() }()
462+
s.eventCh <- event
463+
}()
455464
}
456465

457466
// processEvents is the single consumer goroutine for the event channel.
@@ -657,7 +666,7 @@ func (s *Session) Disconnect() error {
657666
return fmt.Errorf("failed to disconnect session: %w", err)
658667
}
659668

660-
close(s.eventCh)
669+
s.closeOnce.Do(func() { close(s.eventCh) })
661670

662671
// Clear handlers
663672
s.handlerMutex.Lock()

0 commit comments

Comments
 (0)