diff --git a/packages/client/src/Client/Internal/Http2/ConcurrentClientStream.php b/packages/client/src/Client/Internal/Http2/ConcurrentClientStream.php index c1e5777..338f115 100644 --- a/packages/client/src/Client/Internal/Http2/ConcurrentClientStream.php +++ b/packages/client/src/Client/Internal/Http2/ConcurrentClientStream.php @@ -96,7 +96,12 @@ public function close(): void } $this->send->complete(); - $this->complete->await(); + + try { + $this->complete->await(); + } catch (CancelledException $e) { + throw CancellationError::from($e); + } } #[\Override] diff --git a/packages/client/src/ClientStream.php b/packages/client/src/ClientStream.php index f72ab59..37a3eb1 100644 --- a/packages/client/src/ClientStream.php +++ b/packages/client/src/ClientStream.php @@ -43,6 +43,7 @@ public function trailers(Cancellation $cancellation = new NullCancellation()): M /** * @throws ClientStreamIsClosed + * @throws InvokeError */ public function close(): void; } diff --git a/tests/ClientCancellationTest.php b/tests/ClientCancellationTest.php index 0520bee..6d1ca3a 100644 --- a/tests/ClientCancellationTest.php +++ b/tests/ClientCancellationTest.php @@ -13,6 +13,7 @@ use Echos\Api\V1\EchoServiceClient; use Echos\Api\V1\EchoServiceServer; use Echos\Api\V1\EchoServiceServerRegistry; +use File\Api\V1\FileServiceClient; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\TestCase; use Revolt\EventLoop; @@ -115,6 +116,18 @@ public function testStreamCancellationIsCancelled(): void self::assertSame(Code::CANCELLED, $error->statusCode); } + public function testClientStreamCancellationBeforeCloseIsCancelled(): void + { + $cancellation = new DeferredCancellation(); + $stream = new FileServiceClient(new Client\Builder()->withHost(self::ADDRESS)->build()) + ->upload(cancellation: $cancellation->getCancellation()); + $cancellation->cancel(); + + $error = self::catch($stream->close(...)); + + self::assertSame(Code::CANCELLED, $error->statusCode); + } + public function testStreamIterationDeadlineIsDeadlineExceeded(): void { $stream = self::topicClient()->subscribe(new SubscribeRequest('events'), cancellation: new TimeoutCancellation(0.2));