From ac276d143f7369effe6df4fda8164c8e980941d2 Mon Sep 17 00:00:00 2001 From: skraetzig Date: Mon, 21 Sep 2026 22:46:54 +0200 Subject: [PATCH] fix: handle closed TCP connections gracefully Disconnect transports on EOF and prevent cleanup from sending quit commands over connections that were already closed. --- src/Adapter/ServerQuery.php | 3 ++- src/Transport/TCP.php | 1 + tests/Transport/TCPTest.php | 11 ++++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Adapter/ServerQuery.php b/src/Adapter/ServerQuery.php index 3ae2aec..2676820 100644 --- a/src/Adapter/ServerQuery.php +++ b/src/Adapter/ServerQuery.php @@ -6,6 +6,7 @@ use PlanetTeamSpeak\TeamSpeak3Framework\Adapter\ServerQuery\Reply; use PlanetTeamSpeak\TeamSpeak3Framework\Exception\AdapterException; use PlanetTeamSpeak\TeamSpeak3Framework\Exception\ServerQueryException; +use PlanetTeamSpeak\TeamSpeak3Framework\Exception\TransportException; use PlanetTeamSpeak\TeamSpeak3Framework\Helper\Profiler; use PlanetTeamSpeak\TeamSpeak3Framework\Helper\Signal; use PlanetTeamSpeak\TeamSpeak3Framework\Helper\StringHelper; @@ -99,7 +100,7 @@ public function __destruct() if ($this->getTransport() instanceof Transport && $this->transport->isConnected()) { try { $this->request("quit"); - } catch (AdapterException) { + } catch (AdapterException | TransportException) { // The transport destructor will close an unavailable connection. } } diff --git a/src/Transport/TCP.php b/src/Transport/TCP.php index a70d3cd..93c74e4 100644 --- a/src/Transport/TCP.php +++ b/src/Transport/TCP.php @@ -169,6 +169,7 @@ public function readLine(string $token = "\n"): StringHelper if ($data === false) { if (feof($this->stream)) { + $this->disconnect(); throw new TransportException("connection to server '" . $this->config["host"] . ":" . $this->config["port"] . "' lost"); } } else { diff --git a/tests/Transport/TCPTest.php b/tests/Transport/TCPTest.php index 14f932f..bc052de 100644 --- a/tests/Transport/TCPTest.php +++ b/tests/Transport/TCPTest.php @@ -50,9 +50,14 @@ public function setStreamForTest(): void $transport->setStreamForTest(); - $this->expectException(TransportException::class); - $this->expectExceptionMessage("connection to server 'test:12345' lost"); - $transport->readLine(); + try { + $transport->readLine(); + $this->fail('Expected a transport exception for a closed connection.'); + } catch (TransportException $exception) { + $this->assertSame("connection to server 'test:12345' lost", $exception->getMessage()); + } + + $this->assertFalse($transport->isConnected()); } /**