diff --git a/src/Exception/ServerError.php b/src/Exception/ServerError.php index 952a96f..1ffe240 100644 --- a/src/Exception/ServerError.php +++ b/src/Exception/ServerError.php @@ -11,13 +11,32 @@ final class ServerError extends Exception { + private function __construct( + string $message, + int $code, + public readonly int $httpStatusCode, + public readonly string|null $clickHouseExceptionName, + ) { + parent::__construct($message, $code); + } + public static function fromResponse(ResponseInterface $response): self { $bodyContent = $response->getBody()->__toString(); + $errorCode = preg_match('~^Code: (\d+). DB::Exception:~', $bodyContent, $codeMatches) === 1 + ? (int) $codeMatches[1] + : 0; + + $exceptionName = preg_match('~\(([A-Z][A-Z_\d]+)\)~', $bodyContent, $nameMatches) === 1 + ? $nameMatches[1] + : null; + return new self( $bodyContent, - code: preg_match('~^Code: (\\d+). DB::Exception:~', $bodyContent, $matches) === 1 ? (int) $matches[1] : 0, + $errorCode, + $response->getStatusCode(), + $exceptionName, ); } } diff --git a/tests/Exception/ServerErrorTest.php b/tests/Exception/ServerErrorTest.php index b70ac68..5e726f1 100644 --- a/tests/Exception/ServerErrorTest.php +++ b/tests/Exception/ServerErrorTest.php @@ -26,5 +26,22 @@ public function testParseCode(): void $serverError = ServerError::fromResponse($response); self::assertSame(48, $serverError->getCode()); + self::assertSame(501, $serverError->httpStatusCode); + self::assertSame('NOT_IMPLEMENTED', $serverError->clickHouseExceptionName); + } + + public function testParseWithoutExceptionName(): void + { + $psr17Factory = new Psr17Factory(); + $response = $psr17Factory->createResponse(500) + ->withBody( + $psr17Factory->createStream('Some unknown error'), + ); + + $serverError = ServerError::fromResponse($response); + + self::assertSame(0, $serverError->getCode()); + self::assertSame(500, $serverError->httpStatusCode); + self::assertNull($serverError->clickHouseExceptionName); } }