From dd35ad44453416be1911ba6816eedf1c91bb042d Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Tue, 11 Jul 2023 10:49:50 +0200 Subject: [PATCH] Introduce domain exceptions for decoding and encoding --- src/Codec/CodecLibrary.php | 9 ++-- src/Codec/DecodeIfSupported.php | 3 ++ src/Codec/Decoder.php | 4 +- src/Codec/DocumentCodec.php | 3 ++ src/Codec/EncodeIfSupported.php | 3 ++ src/Codec/Encoder.php | 4 +- src/Exception/UnsupportedValueException.php | 55 +++++++++++++++++++++ tests/Codec/CodecLibraryTest.php | 20 +++----- 8 files changed, 77 insertions(+), 24 deletions(-) create mode 100644 src/Exception/UnsupportedValueException.php diff --git a/src/Codec/CodecLibrary.php b/src/Codec/CodecLibrary.php index c4dca9a92..82acb2187 100644 --- a/src/Codec/CodecLibrary.php +++ b/src/Codec/CodecLibrary.php @@ -18,10 +18,7 @@ namespace MongoDB\Codec; use MongoDB\Exception\InvalidArgumentException; -use MongoDB\Exception\UnexpectedValueException; - -use function get_debug_type; -use function sprintf; +use MongoDB\Exception\UnsupportedValueException; class CodecLibrary implements Codec { @@ -129,7 +126,7 @@ final public function decode($value) } } - throw new UnexpectedValueException(sprintf('No decoder found for value of type "%s"', get_debug_type($value))); + throw UnsupportedValueException::invalidDecodableValue($value); } /** @@ -144,6 +141,6 @@ final public function encode($value) } } - throw new UnexpectedValueException(sprintf('No encoder found for value of type "%s"', get_debug_type($value))); + throw UnsupportedValueException::invalidEncodableValue($value); } } diff --git a/src/Codec/DecodeIfSupported.php b/src/Codec/DecodeIfSupported.php index aa26b5b74..56dcfb9ec 100644 --- a/src/Codec/DecodeIfSupported.php +++ b/src/Codec/DecodeIfSupported.php @@ -17,6 +17,8 @@ namespace MongoDB\Codec; +use MongoDB\Exception\UnsupportedValueException; + /** * @psalm-template BSONType * @psalm-template NativeType @@ -34,6 +36,7 @@ abstract public function canDecode($value): bool; * @psalm-param BSONType $value * @return mixed * @psalm-return NativeType + * @throws UnsupportedValueException if the decoder does not support the value */ abstract public function decode($value); diff --git a/src/Codec/Decoder.php b/src/Codec/Decoder.php index d6e07b0e3..904e097fe 100644 --- a/src/Codec/Decoder.php +++ b/src/Codec/Decoder.php @@ -17,7 +17,7 @@ namespace MongoDB\Codec; -use MongoDB\Exception\InvalidArgumentException; +use MongoDB\Exception\UnsupportedValueException; /** * @psalm-template BSONType @@ -41,7 +41,7 @@ public function canDecode($value): bool; * @psalm-param BSONType $value * @return mixed * @psalm-return NativeType - * @throws InvalidArgumentException if the decoder does not support the value + * @throws UnsupportedValueException if the decoder does not support the value */ public function decode($value); diff --git a/src/Codec/DocumentCodec.php b/src/Codec/DocumentCodec.php index e4daa9f47..ba4488b08 100644 --- a/src/Codec/DocumentCodec.php +++ b/src/Codec/DocumentCodec.php @@ -18,6 +18,7 @@ namespace MongoDB\Codec; use MongoDB\BSON\Document; +use MongoDB\Exception\UnsupportedValueException; /** * The DocumentCodec interface allows decoding BSON document data to native PHP @@ -32,12 +33,14 @@ interface DocumentCodec extends Codec * @param mixed $value * @psalm-param Document $value * @psalm-return ObjectType + * @throws UnsupportedValueException if the decoder does not support the value */ public function decode($value): object; /** * @param mixed $value * @psalm-param ObjectType $value + * @throws UnsupportedValueException if the encoder does not support the value */ public function encode($value): Document; } diff --git a/src/Codec/EncodeIfSupported.php b/src/Codec/EncodeIfSupported.php index 7e579bc6b..c4aebac6b 100644 --- a/src/Codec/EncodeIfSupported.php +++ b/src/Codec/EncodeIfSupported.php @@ -17,6 +17,8 @@ namespace MongoDB\Codec; +use MongoDB\Exception\UnsupportedValueException; + /** * @psalm-template BSONType * @psalm-template NativeType @@ -34,6 +36,7 @@ abstract public function canEncode($value): bool; * @psalm-param NativeType $value * @return mixed * @psalm-return BSONType + * @throws UnsupportedValueException if the encoder does not support the value */ abstract public function encode($value); diff --git a/src/Codec/Encoder.php b/src/Codec/Encoder.php index ba5343f80..dba58d9d5 100644 --- a/src/Codec/Encoder.php +++ b/src/Codec/Encoder.php @@ -17,7 +17,7 @@ namespace MongoDB\Codec; -use MongoDB\Exception\InvalidArgumentException; +use MongoDB\Exception\UnsupportedValueException; /** * @psalm-template BSONType @@ -41,7 +41,7 @@ public function canEncode($value): bool; * @psalm-param NativeType $value * @return mixed * @psalm-return BSONType - * @throws InvalidArgumentException if the decoder does not support the value + * @throws UnsupportedValueException if the encoder does not support the value */ public function encode($value); diff --git a/src/Exception/UnsupportedValueException.php b/src/Exception/UnsupportedValueException.php new file mode 100644 index 000000000..33635d8a0 --- /dev/null +++ b/src/Exception/UnsupportedValueException.php @@ -0,0 +1,55 @@ +value; + } + + /** @param mixed $value */ + public static function invalidDecodableValue($value): self + { + return new self(sprintf('Could not decode value of type "%s".', get_debug_type($value)), $value); + } + + /** @param mixed $value */ + public static function invalidEncodableValue($value): self + { + return new self(sprintf('Could not encode value of type "%s".', get_debug_type($value)), $value); + } + + /** @param mixed $value */ + private function __construct(string $message, $value) + { + parent::__construct($message); + + $this->value = $value; + } +} diff --git a/tests/Codec/CodecLibraryTest.php b/tests/Codec/CodecLibraryTest.php index 6fd1643f6..489e1d1d8 100644 --- a/tests/Codec/CodecLibraryTest.php +++ b/tests/Codec/CodecLibraryTest.php @@ -7,7 +7,7 @@ use MongoDB\Codec\DecodeIfSupported; use MongoDB\Codec\EncodeIfSupported; use MongoDB\Codec\KnowsCodecLibrary; -use MongoDB\Exception\UnexpectedValueException; +use MongoDB\Exception\UnsupportedValueException; use MongoDB\Tests\TestCase; class CodecLibraryTest extends TestCase @@ -36,17 +36,13 @@ public function testDecodeNull(): void $this->assertFalse($codec->canDecode(null)); - $this->expectException(UnexpectedValueException::class); - $this->expectExceptionMessage('No decoder found for value of type "null"'); - - $this->assertNull($codec->decode(null)); + $this->expectExceptionObject(UnsupportedValueException::invalidDecodableValue(null)); + $codec->decode(null); } public function testDecodeUnsupportedValue(): void { - $this->expectException(UnexpectedValueException::class); - $this->expectExceptionMessage('No decoder found for value of type "string"'); - + $this->expectExceptionObject(UnsupportedValueException::invalidDecodableValue('foo')); $this->getCodecLibrary()->decode('foo'); } @@ -74,17 +70,13 @@ public function testEncodeNull(): void $this->assertFalse($codec->canEncode(null)); - $this->expectException(UnexpectedValueException::class); - $this->expectExceptionMessage('No encoder found for value of type "null"'); - + $this->expectExceptionObject(UnsupportedValueException::invalidEncodableValue(null)); $codec->encode(null); } public function testEncodeUnsupportedValue(): void { - $this->expectException(UnexpectedValueException::class); - $this->expectExceptionMessage('No encoder found for value of type "string"'); - + $this->expectExceptionObject(UnsupportedValueException::invalidEncodableValue('foo')); $this->getCodecLibrary()->encode('foo'); }