Skip to content

Commit 60b036d

Browse files
author
klapaudius
committed
Introduce SseAdapterException for more specific error handling
Replaces generic Exception with SseAdapterException in SseAdapter-related classes. Improves error specificity and aligns exception types with the domain logic, enhancing maintainability and debugging clarity.
1 parent 55b7157 commit 60b036d

File tree

6 files changed

+38
-27
lines changed

6 files changed

+38
-27
lines changed

src/Server/Notification/PongHandler.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Exception;
66
use KLP\KlpMcpServer\Protocol\Handlers\NotificationHandler;
7+
use KLP\KlpMcpServer\Transports\SseAdapters\SseAdapterException;
78
use KLP\KlpMcpServer\Transports\SseAdapters\SseAdapterInterface;
89

910
/**
@@ -31,7 +32,7 @@ public function execute(?array $params = null): array
3132
{
3233
try {
3334
$this->adapter?->storeLastPongResponseTimestamp($params['clientId'], time());
34-
} catch (Exception) {
35+
} catch (SseAdapterException) {
3536
// Nothing to do here the client will be disconnected anyway
3637
}
3738

src/Transports/SseAdapters/RedisAdapter.php

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public function __construct(
4545
$this->redis->setOption(Redis::OPT_PREFIX, $this->keyPrefix);
4646
} catch (Exception $e) {
4747
$this->logger?->error(self::FAILED_TO_INITIALIZE.$e->getMessage());
48-
throw new \Exception(self::FAILED_TO_INITIALIZE.$e->getMessage());
48+
throw new SseAdapterException(self::FAILED_TO_INITIALIZE.$e->getMessage());
4949
}
5050
}
5151

@@ -55,7 +55,7 @@ public function __construct(
5555
* @param string $clientId The unique identifier for the client
5656
* @param string $message The message to be queued
5757
*
58-
* @throws Exception If the message cannot be added to the queue
58+
* @throws SseAdapterException If the message cannot be added to the queue
5959
*/
6060
public function pushMessage(string $clientId, string $message): void
6161
{
@@ -68,7 +68,7 @@ public function pushMessage(string $clientId, string $message): void
6868

6969
} catch (Exception $e) {
7070
$this->logger?->error('Failed to add message to Redis queue: '.$e->getMessage());
71-
throw new Exception('Failed to add message to Redis queue: '.$e->getMessage());
71+
throw new SseAdapterException('Failed to add message to Redis queue: '.$e->getMessage());
7272
}
7373
}
7474

@@ -88,7 +88,7 @@ protected function getQueueKey(string $clientId): string
8888
*
8989
* @param string $clientId The unique identifier for the client
9090
*
91-
* @throws Exception If the messages cannot be removed
91+
* @throws SseAdapterException If the messages cannot be removed
9292
*/
9393
public function removeAllMessages(string $clientId): void
9494
{
@@ -99,7 +99,7 @@ public function removeAllMessages(string $clientId): void
9999

100100
} catch (Exception $e) {
101101
$this->logger?->error('Failed to remove messages from Redis queue: '.$e->getMessage());
102-
throw new Exception('Failed to remove messages from Redis queue: '.$e->getMessage());
102+
throw new SseAdapterException('Failed to remove messages from Redis queue: '.$e->getMessage());
103103
}
104104
}
105105

@@ -109,7 +109,7 @@ public function removeAllMessages(string $clientId): void
109109
* @param string $clientId The unique identifier for the client
110110
* @return array<string> Array of messages
111111
*
112-
* @throws Exception If the messages cannot be retrieved
112+
* @throws SseAdapterException If the messages cannot be retrieved
113113
*/
114114
public function receiveMessages(string $clientId): array
115115
{
@@ -123,7 +123,7 @@ public function receiveMessages(string $clientId): array
123123

124124
return $messages;
125125
} catch (Exception $e) {
126-
throw new Exception('Failed to receive messages from Redis queue: '.$e->getMessage());
126+
throw new SseAdapterException('Failed to receive messages from Redis queue: '.$e->getMessage());
127127
}
128128
}
129129

@@ -133,7 +133,7 @@ public function receiveMessages(string $clientId): array
133133
* @param string $clientId The unique identifier for the client
134134
* @return string|null The message or null if the queue is empty
135135
*
136-
* @throws Exception If the message cannot be popped
136+
* @throws SseAdapterException If the message cannot be popped
137137
*/
138138
public function popMessage(string $clientId): ?string
139139
{
@@ -149,7 +149,7 @@ public function popMessage(string $clientId): ?string
149149
return $message;
150150
} catch (Exception $e) {
151151
$this->logger?->error('Failed to pop message from Redis queue: '.$e->getMessage());
152-
throw new Exception('Failed to pop message from Redis queue: '.$e->getMessage());
152+
throw new SseAdapterException('Failed to pop message from Redis queue: '.$e->getMessage());
153153
}
154154
}
155155

@@ -201,7 +201,7 @@ public function getMessageCount(string $clientId): int
201201
* @param string $clientId The unique identifier for the client
202202
* @param int|null $timestamp The timestamp to store (defaults to current time if null)
203203
*
204-
* @throws Exception If the timestamp cannot be stored
204+
* @throws SseAdapterException If the timestamp cannot be stored
205205
*/
206206
public function storeLastPongResponseTimestamp(string $clientId, ?int $timestamp = null): void
207207
{
@@ -214,7 +214,7 @@ public function storeLastPongResponseTimestamp(string $clientId, ?int $timestamp
214214

215215
} catch (Exception $e) {
216216
$this->logger?->error('Failed to store last pong timestamp: '.$e->getMessage());
217-
throw new Exception('Failed to store last pong timestamp: '.$e->getMessage());
217+
throw new SseAdapterException('Failed to store last pong timestamp: '.$e->getMessage());
218218
}
219219
}
220220

@@ -224,7 +224,7 @@ public function storeLastPongResponseTimestamp(string $clientId, ?int $timestamp
224224
* @param string $clientId The unique identifier for the client
225225
* @return int|null The timestamp or null if no timestamp is stored
226226
*
227-
* @throws Exception If the timestamp cannot be retrieved
227+
* @throws SseAdapterException If the timestamp cannot be retrieved
228228
*/
229229
public function getLastPongResponseTimestamp(string $clientId): ?int
230230
{
@@ -241,7 +241,7 @@ public function getLastPongResponseTimestamp(string $clientId): ?int
241241

242242
} catch (Exception $e) {
243243
$this->logger?->error('Failed to get last pong timestamp: '.$e->getMessage());
244-
throw new Exception('Failed to get last pong timestamp: '.$e->getMessage());
244+
throw new SseAdapterException('Failed to get last pong timestamp: '.$e->getMessage());
245245
}
246246
}
247247
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace KLP\KlpMcpServer\Transports\SseAdapters;
4+
5+
use Exception;
6+
7+
class SseAdapterException extends Exception {}

src/Transports/SseAdapters/SseAdapterInterface.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ interface SseAdapterInterface
1919
* @param string $clientId The unique identifier for the client
2020
* @param string $message The message to be queued
2121
*
22-
* @throws \Exception If the message cannot be added to the queue
22+
* @throws SseAdapterException If the message cannot be added to the queue
2323
*/
2424
public function pushMessage(string $clientId, string $message): void;
2525

@@ -28,7 +28,7 @@ public function pushMessage(string $clientId, string $message): void;
2828
*
2929
* @param string $clientId The unique identifier for the client
3030
*
31-
* @throws \Exception If the messages cannot be removed
31+
* @throws SseAdapterException If the messages cannot be removed
3232
*/
3333
public function removeAllMessages(string $clientId): void;
3434

@@ -38,7 +38,7 @@ public function removeAllMessages(string $clientId): void;
3838
* @param string $clientId The unique identifier for the client
3939
* @return array<string> Array of messages
4040
*
41-
* @throws \Exception If the messages cannot be retrieved
41+
* @throws SseAdapterException If the messages cannot be retrieved
4242
*/
4343
public function receiveMessages(string $clientId): array;
4444

@@ -48,7 +48,7 @@ public function receiveMessages(string $clientId): array;
4848
* @param string $clientId The unique identifier for the client
4949
* @return string|null The message or null if the queue is empty
5050
*
51-
* @throws \Exception If the message cannot be popped
51+
* @throws SseAdapterException If the message cannot be popped
5252
*/
5353
public function popMessage(string $clientId): ?string;
5454

@@ -74,7 +74,7 @@ public function getMessageCount(string $clientId): int;
7474
* @param string $clientId The unique identifier for the client
7575
* @param int|null $timestamp The timestamp to store (defaults to current time if null)
7676
*
77-
* @throws \Exception If the timestamp cannot be stored
77+
* @throws SseAdapterException If the timestamp cannot be stored
7878
*/
7979
public function storeLastPongResponseTimestamp(string $clientId, ?int $timestamp = null): void;
8080

@@ -84,7 +84,7 @@ public function storeLastPongResponseTimestamp(string $clientId, ?int $timestamp
8484
* @param string $clientId The unique identifier for the client
8585
* @return int|null The timestamp or null if no timestamp is stored
8686
*
87-
* @throws \Exception If the timestamp cannot be retrieved
87+
* @throws SseAdapterException If the timestamp cannot be retrieved
8888
*/
8989
public function getLastPongResponseTimestamp(string $clientId): ?int;
9090
}

src/Transports/SseTransport.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace KLP\KlpMcpServer\Transports;
44

55
use Exception;
6+
use KLP\KlpMcpServer\Transports\SseAdapters\SseAdapterException;
67
use KLP\KlpMcpServer\Transports\SseAdapters\SseAdapterInterface;
78
use Psr\Log\LoggerInterface;
89

@@ -98,15 +99,15 @@ public function start(): void
9899
* Initializes the transport: generates client ID and sends the initial 'endpoint' event.
99100
* Adapter-specific initialization might occur here or externally.
100101
*
101-
* @throws Exception If sending the initial event fails.
102+
* @throws SseAdapterException If sending the initial event fails.
102103
*/
103104
public function initialize(): void
104105
{
105106
if ($this->clientId === null) {
106107
$this->clientId = uniqid();
107108
}
108109
$this->lastPingTimestamp = time();
109-
$this->adapter->storeLastPongResponseTimestamp($this->clientId, time());
110+
$this->adapter?->storeLastPongResponseTimestamp($this->clientId, time());
110111

111112
$this->sendEvent(event: 'endpoint', data: $this->getEndpoint(sessionId: $this->clientId));
112113
}
@@ -173,7 +174,7 @@ public function close(): void
173174
if ($this->adapter !== null && $this->clientId !== null) {
174175
try {
175176
$this->adapter->removeAllMessages($this->clientId);
176-
} catch (Exception $e) {
177+
} catch (SseAdapterException $e) {
177178
$this->logger?->error('Error cleaning up SSE adapter resources on close: '.$e->getMessage());
178179
}
179180
}
@@ -245,7 +246,7 @@ public function receive(): array
245246
$messages = $this->adapter->receiveMessages($this->clientId);
246247

247248
return $messages ?: [];
248-
} catch (Exception $e) {
249+
} catch (SseAdapterException $e) {
249250
$this->triggerError('SSE Failed to receive messages via adapter: '.$e->getMessage());
250251
}
251252
} elseif ($this->adapter === null) {
@@ -338,7 +339,8 @@ private function getEndpoint(string $sessionId): string
338339
}
339340

340341
/**
341-
* @throws Exception
342+
* @return int|null
343+
* @throws SseAdapterException
342344
*/
343345
protected function getLastPongResponseTimestamp(): ?int
344346
{

tests/Transports/SseTransportTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace KLP\KlpMcpServer\Tests\Transports;
44

5+
use KLP\KlpMcpServer\Transports\SseAdapters\SseAdapterException;
56
use KLP\KlpMcpServer\Transports\SseAdapters\SseAdapterInterface;
67
use KLP\KlpMcpServer\Transports\SseTransport;
78
use KLP\KlpMcpServer\Transports\SseTransportException;
@@ -310,7 +311,7 @@ public function test_close_logs_exceptions_in_handlers_or_cleanup(): void
310311
$this->setProtectedProperty($this->instance, 'clientId', 'test-client-id');
311312
$adapterMock->expects($this->once())
312313
->method('removeAllMessages')
313-
->willThrowException(new \Exception('Adapter Exception'));
314+
->willThrowException(new SseAdapterException('Adapter Exception'));
314315

315316
// Act
316317
ob_start();
@@ -404,7 +405,7 @@ public function test_receive_triggers_error_handlers_on_adapter_exception(): voi
404405

405406
$adapterMock->expects($this->once())
406407
->method('receiveMessages')
407-
->willThrowException(new \Exception('Adapter Exception'));
408+
->willThrowException(new SseAdapterException('Adapter Exception'));
408409

409410
$errorTriggered = false;
410411
$this->instance->onError(function (string $error) use (&$errorTriggered) {

0 commit comments

Comments
 (0)