Skip to content

Commit 8900b8e

Browse files
outdooracornSilvan-WMDE
authored andcommitted
Throw more specific exceptions in JsonPatch::import() (#1)
- UnknownOperationException - MissingFieldException Co-authored-by: sihe <[email protected]>
1 parent ccfc713 commit 8900b8e

File tree

4 files changed

+96
-7
lines changed

4 files changed

+96
-7
lines changed

src/JsonPatch.php

+9-5
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,15 @@ public static function import(array $data)
6060
$operation = (object)$operation;
6161
}
6262

63+
if (!is_object($operation)) {
64+
throw new Exception( 'Invalid patch operation - should be a JSON object' );
65+
}
66+
6367
if (!isset($operation->op)) {
64-
throw new Exception('Missing "op" in operation data');
68+
throw new MissingFieldException('op', $operation);
6569
}
6670
if (!isset($operation->path)) {
67-
throw new Exception('Missing "path" in operation data');
71+
throw new MissingFieldException('path', $operation);
6872
}
6973

7074
$op = null;
@@ -88,18 +92,18 @@ public static function import(array $data)
8892
$op = new Test();
8993
break;
9094
default:
91-
throw new Exception('Unknown "op": ' . $operation->op);
95+
throw new UnknownOperationException($operation);
9296
}
9397
$op->path = $operation->path;
9498
if ($op instanceof OpPathValue) {
9599
if (property_exists($operation, 'value')) {
96100
$op->value = $operation->value;
97101
} else {
98-
throw new Exception('Missing "value" in operation data');
102+
throw new MissingFieldException('value', $operation);
99103
}
100104
} elseif ($op instanceof OpPathFrom) {
101105
if (!isset($operation->from)) {
102-
throw new Exception('Missing "from" in operation data');
106+
throw new MissingFieldException('from', $operation);
103107
}
104108
$op->from = $operation->from;
105109
}

src/MissingFieldException.php

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace Swaggest\JsonDiff;
4+
5+
use Throwable;
6+
7+
class MissingFieldException extends Exception
8+
{
9+
/** @var string */
10+
private $missingField;
11+
/** @var object */
12+
private $operation;
13+
14+
/**
15+
* @param string $missingField
16+
* @param object $operation
17+
* @param int $code
18+
* @param Throwable|null $previous
19+
*/
20+
public function __construct(
21+
$missingField,
22+
$operation,
23+
$code = 0,
24+
Throwable $previous = null
25+
)
26+
{
27+
parent::__construct('Missing "' . $missingField . '" in operation data', $code, $previous);
28+
$this->missingField = $missingField;
29+
$this->operation = $operation;
30+
}
31+
32+
/**
33+
* @return string
34+
*/
35+
public function getMissingField()
36+
{
37+
return $this->missingField;
38+
}
39+
40+
/**
41+
* @return object
42+
*/
43+
public function getOperation()
44+
{
45+
return $this->operation;
46+
}
47+
}

src/UnknownOperationException.php

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Swaggest\JsonDiff;
4+
5+
6+
use Throwable;
7+
8+
class UnknownOperationException extends Exception
9+
{
10+
/** @var object */
11+
private $operation;
12+
13+
/**
14+
* @param object $operation
15+
* @param int $code
16+
* @param Throwable|null $previous
17+
*/
18+
public function __construct(
19+
$operation,
20+
$code = 0,
21+
Throwable $previous = null
22+
)
23+
{
24+
// @phpstan-ignore-next-line MissingFieldOperation will be thrown if op is not set
25+
parent::__construct('Unknown "op": ' . $operation->op, $code, $previous);
26+
$this->operation = $operation;
27+
}
28+
29+
/**
30+
* @return object
31+
*/
32+
public function getOperation()
33+
{
34+
return $this->operation;
35+
}
36+
}

tests/src/JsonPatchTest.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
use Swaggest\JsonDiff\Exception;
66
use Swaggest\JsonDiff\JsonDiff;
77
use Swaggest\JsonDiff\JsonPatch;
8+
use Swaggest\JsonDiff\MissingFieldException;
89
use Swaggest\JsonDiff\PatchTestOperationFailedException;
10+
use Swaggest\JsonDiff\UnknownOperationException;
911

1012
class JsonPatchTest extends \PHPUnit_Framework_TestCase
1113
{
@@ -75,7 +77,7 @@ public function testNull()
7577

7678
public function testMissingOp()
7779
{
78-
$this->setExpectedException(get_class(new Exception()), 'Missing "op" in operation data');
80+
$this->setExpectedException(MissingFieldException::class, 'Missing "op" in operation data');
7981
JsonPatch::import(array((object)array('path' => '/123')));
8082
}
8183

@@ -87,7 +89,7 @@ public function testMissingPath()
8789

8890
public function testInvalidOp()
8991
{
90-
$this->setExpectedException(get_class(new Exception()), 'Unknown "op": wat');
92+
$this->setExpectedException(UnknownOperationException::class, 'Unknown "op": wat');
9193
JsonPatch::import(array((object)array('op' => 'wat', 'path' => '/123')));
9294
}
9395

0 commit comments

Comments
 (0)