diff --git a/src/Message/Stream.php b/src/Message/Stream.php index ecc14c3..bcdf355 100644 --- a/src/Message/Stream.php +++ b/src/Message/Stream.php @@ -48,6 +48,8 @@ private function __construct() } /** + * @throws \Throwable + * * @return string */ public function __toString(): string @@ -271,6 +273,7 @@ public function read($length): string /** * @throws \RuntimeException + * @throws \Throwable * * @return string */ @@ -280,14 +283,31 @@ public function getContents(): string throw new \RuntimeException('Unable to read stream contents'); } - $contents = \stream_get_contents($this->stream); + $exception = null; - if ($contents === false) { - // @codeCoverageIgnoreStart - /* Could not reach this statement without mocking the filesystem - */ - throw new \RuntimeException('Unable to read stream contents'); - // @codeCoverageIgnoreEnd + \set_error_handler(static function ($type, $message) use (&$exception) { + throw $exception = new \RuntimeException('Unable to read stream contents: ' . $message); + }); + + try { + $contents = \stream_get_contents($this->stream); + + if ($contents === false) { + // @codeCoverageIgnoreStart + /* Could not reach this statement without changing php-src + * @info: https://github.com/php/php-src/blob/311cae03e730c76aed343312319ed8cf1c37ade0/main/streams/streams.c#L1512 + */ + $exception = new \RuntimeException('Unable to read stream contents'); + // @codeCoverageIgnoreEnd + } + } catch (\Throwable $e) { + $exception = new \RuntimeException('Unable to read stream contents: ' . $e->getMessage(), 0, $e); + } + + \restore_error_handler(); + + if ($exception) { + throw $exception; } return $contents; diff --git a/tests/StreamTest.php b/tests/StreamTest.php index 0dfac9f..f40902b 100644 --- a/tests/StreamTest.php +++ b/tests/StreamTest.php @@ -53,6 +53,20 @@ public function testGetsContents(): void static::assertSame('', $stream->getContents()); } + public function testGetsContentsRaiseException(): void + { + $handle = \fopen(\tempnam(\sys_get_temp_dir(), 'rancoud/http'), 'r+'); + + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Unable to read stream contents'); + + $stream = Stream::create($handle); + + \fclose($handle); + + $stream->getContents(); + } + public function testChecksEof(): void { $handle = \fopen('php://temp', 'w+');