From cf5bac461e6f853b55a1c804069e5d2a6edbf70d Mon Sep 17 00:00:00 2001 From: Ollie Shotton Date: Thu, 13 Oct 2022 17:08:52 +0100 Subject: [PATCH 1/2] Throw more specific exceptions in `JsonPatch::import()` - InvalidOperationException - MissingFieldException --- src/InvalidOperationException.php | 32 +++++++++++++++++++++++++++++ src/JsonPatch.php | 14 ++++++++----- src/MissingFieldException.php | 34 +++++++++++++++++++++++++++++++ tests/src/JsonPatchTest.php | 5 +++-- 4 files changed, 78 insertions(+), 7 deletions(-) create mode 100644 src/InvalidOperationException.php create mode 100644 src/MissingFieldException.php diff --git a/src/InvalidOperationException.php b/src/InvalidOperationException.php new file mode 100644 index 0000000..feeb9e2 --- /dev/null +++ b/src/InvalidOperationException.php @@ -0,0 +1,32 @@ +operationObject = $operationObject; + } + + public function getInvalidOperation(): string + { + return $this->operationObject->op; + } + + public function getOperationObject(): object + { + return $this->operationObject; + } +} diff --git a/src/JsonPatch.php b/src/JsonPatch.php index 62a80f2..7642928 100644 --- a/src/JsonPatch.php +++ b/src/JsonPatch.php @@ -60,11 +60,15 @@ public static function import(array $data) $operation = (object)$operation; } + if (!is_object($operation)) { + throw new Exception( 'Invalid patch operation - should be a JSON object' ); + } + if (!isset($operation->op)) { - throw new Exception('Missing "op" in operation data'); + throw new MissingFieldException('op', $operation, 'Missing "op" in operation data'); } if (!isset($operation->path)) { - throw new Exception('Missing "path" in operation data'); + throw new MissingFieldException('path', $operation, 'Missing "path" in operation data'); } $op = null; @@ -88,18 +92,18 @@ public static function import(array $data) $op = new Test(); break; default: - throw new Exception('Unknown "op": ' . $operation->op); + throw new InvalidOperationException($operation, 'Invalid "op": ' . $operation->op); } $op->path = $operation->path; if ($op instanceof OpPathValue) { if (property_exists($operation, 'value')) { $op->value = $operation->value; } else { - throw new Exception('Missing "value" in operation data'); + throw new MissingFieldException('value', $operation, 'Missing "value" in operation data'); } } elseif ($op instanceof OpPathFrom) { if (!isset($operation->from)) { - throw new Exception('Missing "from" in operation data'); + throw new MissingFieldException('from', $operation, 'Missing "from" in operation data'); } $op->from = $operation->from; } diff --git a/src/MissingFieldException.php b/src/MissingFieldException.php new file mode 100644 index 0000000..0cb7ae8 --- /dev/null +++ b/src/MissingFieldException.php @@ -0,0 +1,34 @@ +missingField = $missingField; + $this->operationObject = $operationObject; + } + + public function getMissingField(): string + { + return $this->missingField; + } + + public function getOperationObject(): object + { + return $this->operationObject; + } +} diff --git a/tests/src/JsonPatchTest.php b/tests/src/JsonPatchTest.php index 0870442..133d3e0 100644 --- a/tests/src/JsonPatchTest.php +++ b/tests/src/JsonPatchTest.php @@ -5,6 +5,7 @@ use Swaggest\JsonDiff\Exception; use Swaggest\JsonDiff\JsonDiff; use Swaggest\JsonDiff\JsonPatch; +use Swaggest\JsonDiff\MissingFieldException; use Swaggest\JsonDiff\PatchTestOperationFailedException; class JsonPatchTest extends \PHPUnit_Framework_TestCase @@ -75,7 +76,7 @@ public function testNull() public function testMissingOp() { - $this->setExpectedException(get_class(new Exception()), 'Missing "op" in operation data'); + $this->setExpectedException(MissingFieldException::class, 'Missing "op" in operation data'); JsonPatch::import(array((object)array('path' => '/123'))); } @@ -87,7 +88,7 @@ public function testMissingPath() public function testInvalidOp() { - $this->setExpectedException(get_class(new Exception()), 'Unknown "op": wat'); + $this->setExpectedException(get_class(new Exception()), 'Invalid "op": wat'); JsonPatch::import(array((object)array('op' => 'wat', 'path' => '/123'))); } From d9a22ad91aa16051f2b864311104ae21e6171b3c Mon Sep 17 00:00:00 2001 From: sihe Date: Mon, 17 Oct 2022 14:51:11 +0200 Subject: [PATCH 2/2] Polish new import Exceptions * rename Invalid... -> Unknown... * make PHP 5.6 compatible * create message inside Exceptions --- src/InvalidOperationException.php | 32 --------------------------- src/JsonPatch.php | 10 ++++----- src/MissingFieldException.php | 35 ++++++++++++++++++++---------- src/UnknownOperationException.php | 36 +++++++++++++++++++++++++++++++ tests/src/JsonPatchTest.php | 3 ++- 5 files changed, 67 insertions(+), 49 deletions(-) delete mode 100644 src/InvalidOperationException.php create mode 100644 src/UnknownOperationException.php diff --git a/src/InvalidOperationException.php b/src/InvalidOperationException.php deleted file mode 100644 index feeb9e2..0000000 --- a/src/InvalidOperationException.php +++ /dev/null @@ -1,32 +0,0 @@ -operationObject = $operationObject; - } - - public function getInvalidOperation(): string - { - return $this->operationObject->op; - } - - public function getOperationObject(): object - { - return $this->operationObject; - } -} diff --git a/src/JsonPatch.php b/src/JsonPatch.php index 7642928..ccd4c99 100644 --- a/src/JsonPatch.php +++ b/src/JsonPatch.php @@ -65,10 +65,10 @@ public static function import(array $data) } if (!isset($operation->op)) { - throw new MissingFieldException('op', $operation, 'Missing "op" in operation data'); + throw new MissingFieldException('op', $operation); } if (!isset($operation->path)) { - throw new MissingFieldException('path', $operation, 'Missing "path" in operation data'); + throw new MissingFieldException('path', $operation); } $op = null; @@ -92,18 +92,18 @@ public static function import(array $data) $op = new Test(); break; default: - throw new InvalidOperationException($operation, 'Invalid "op": ' . $operation->op); + throw new UnknownOperationException($operation); } $op->path = $operation->path; if ($op instanceof OpPathValue) { if (property_exists($operation, 'value')) { $op->value = $operation->value; } else { - throw new MissingFieldException('value', $operation, 'Missing "value" in operation data'); + throw new MissingFieldException('value', $operation); } } elseif ($op instanceof OpPathFrom) { if (!isset($operation->from)) { - throw new MissingFieldException('from', $operation, 'Missing "from" in operation data'); + throw new MissingFieldException('from', $operation); } $op->from = $operation->from; } diff --git a/src/MissingFieldException.php b/src/MissingFieldException.php index 0cb7ae8..915f1dc 100644 --- a/src/MissingFieldException.php +++ b/src/MissingFieldException.php @@ -6,29 +6,42 @@ class MissingFieldException extends Exception { - private string $missingField; - private object $operationObject; + /** @var string */ + private $missingField; + /** @var object */ + private $operation; + /** + * @param string $missingField + * @param object $operation + * @param int $code + * @param Throwable|null $previous + */ public function __construct( - string $missingField, - object $operationObject, - string $message = '', - int $code = 0, + $missingField, + $operation, + $code = 0, Throwable $previous = null ) { - parent::__construct($message, $code, $previous); + parent::__construct('Missing "' . $missingField . '" in operation data', $code, $previous); $this->missingField = $missingField; - $this->operationObject = $operationObject; + $this->operation = $operation; } - public function getMissingField(): string + /** + * @return string + */ + public function getMissingField() { return $this->missingField; } - public function getOperationObject(): object + /** + * @return object + */ + public function getOperation() { - return $this->operationObject; + return $this->operation; } } diff --git a/src/UnknownOperationException.php b/src/UnknownOperationException.php new file mode 100644 index 0000000..0855bb2 --- /dev/null +++ b/src/UnknownOperationException.php @@ -0,0 +1,36 @@ +op, $code, $previous); + $this->operation = $operation; + } + + /** + * @return object + */ + public function getOperation() + { + return $this->operation; + } +} diff --git a/tests/src/JsonPatchTest.php b/tests/src/JsonPatchTest.php index 133d3e0..ce73ab6 100644 --- a/tests/src/JsonPatchTest.php +++ b/tests/src/JsonPatchTest.php @@ -7,6 +7,7 @@ use Swaggest\JsonDiff\JsonPatch; use Swaggest\JsonDiff\MissingFieldException; use Swaggest\JsonDiff\PatchTestOperationFailedException; +use Swaggest\JsonDiff\UnknownOperationException; class JsonPatchTest extends \PHPUnit_Framework_TestCase { @@ -88,7 +89,7 @@ public function testMissingPath() public function testInvalidOp() { - $this->setExpectedException(get_class(new Exception()), 'Invalid "op": wat'); + $this->setExpectedException(UnknownOperationException::class, 'Unknown "op": wat'); JsonPatch::import(array((object)array('op' => 'wat', 'path' => '/123'))); }