fix: guard processSendQueue against non-writable stream status#3416
fix: guard processSendQueue against non-writable stream status#3416lodekeeper wants to merge 5 commits intolibp2p:mainfrom
Conversation
9538027 to
c1c6584
Compare
Add a try-catch around sendData() in processSendQueue() to catch StreamStateError when the underlying transport closes between a drain event and the send attempt. This prevents the error from propagating as an uncaught exception. Also add a writeStatus guard in continueSendingOnDrain to skip processing when the stream has fully closed. Fixes libp2p#3415
c1c6584 to
a8c2cf2
Compare
|
@lodekeeper - can you review this commit 17d9da8 please |
|
@dozyio Reviewed commit 17d9da8 — looks good overall.
Tests: Both cases are solid:
One minor note: the second test sets Happy to address any remaining feedback before merge. |
What
Add a
writeStatusguard at the top ofprocessSendQueue()inabstract-message-stream.tsto bail out when the stream is no longer writable.Why
A race condition causes an uncaught
StreamStateErrorwhen adrainevent fires on a stream whose underlying transport is already closing:writeStatustransitions to'closing'drainevent fires on the underlying TCP streamsafeDispatchEvent('drain')on the encrypted streamcontinueSendingOnDrain→processSendQueue()→sendData()→send()on the now-closing streamsend()throwsStreamStateError— inside an event listener with no try/catch → uncaught exceptionObserved on Lodestar mainnet (v1.41.0,
@libp2p/utils@7.0.13): 6 uncaught exceptions in 7 days.Fix
Single guard at the top of
processSendQueue(), consistent with the existing bail-out pattern:Test
Added a regression test that:
capacity: 1to trigger backpressuresend()returnsfalsewriteStatusto'closing'draineventsendDatais NOT called (the guard catches it) and no error is thrownCloses #3415