From a9a81e9c010cd0071f40cbac79fc5c6ce2d625e7 Mon Sep 17 00:00:00 2001 From: Tobias Kantusch Date: Fri, 2 Jun 2023 14:56:14 +0200 Subject: [PATCH] fix(async): handle close of packet stream to avoid panic When the packet stream closes, e.g. because the server terminated the connection, the stream returns None. Then, the next() function shouldn't be called again on the stream, as it is already closed. Previously, we wouldn't handle this, which lead to a panic. Before the fix which implemented the as_stream() function for the socket, the program wouldn't panic, but instead run in an endless loop which isn't ideal either. Now, the loop which fetches the packets from the stream properly terminates. However, the program which uses the socket.io client currently isn't notified of the unexpected closure. --- socketio/src/asynchronous/client/builder.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/socketio/src/asynchronous/client/builder.rs b/socketio/src/asynchronous/client/builder.rs index ba85b8eb..e2b0e962 100644 --- a/socketio/src/asynchronous/client/builder.rs +++ b/socketio/src/asynchronous/client/builder.rs @@ -343,14 +343,10 @@ impl ClientBuilder { // Use thread to consume items in iterator in order to call callbacks tokio::runtime::Handle::current().spawn(async move { let mut stream = socket_clone.as_stream(); - loop { - // tries to restart a poll cycle whenever a 'normal' error occurs, - // it just logs on network errors, in case the poll cycle returned - // `Result::Ok`, the server receives a close frame so it's safe to - // terminate - if let Some(e @ Err(Error::IncompleteResponseFromEngineIo(_))) = stream.next().await - { - trace!("Network error occured: {}", e.unwrap_err()); + // Consume the stream until it returns None and the stream is closed. + while let Some(item) = stream.next().await { + if let e @ Err(Error::IncompleteResponseFromEngineIo(_)) = item { + trace!("Network error occurred: {}", e.unwrap_err()); } } });