Skip to content

Commit a84c84d

Browse files
authored
Merge pull request #4 from carsdotcom/hotfix/error-disappears-during-reporting
fix:this->error can be reset in the middle of validateOrThrow
2 parents 5590c31 + 535dfb9 commit a84c84d

File tree

2 files changed

+26
-46
lines changed

2 files changed

+26
-46
lines changed

app/SchemaValidatorService.php

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Opis\JsonSchema\Errors\ErrorFormatter;
1616
use Opis\JsonSchema\Errors\ValidationError;
1717
use Opis\JsonSchema\Uri;
18+
use Opis\JsonSchema\ValidationResult;
1819
use Opis\JsonSchema\Validator;
1920
use Symfony\Component\HttpFoundation\Response;
2021

@@ -23,12 +24,6 @@ class SchemaValidatorService
2324
/** @var Validator */
2425
protected $validator = null;
2526

26-
/**
27-
* error from the most recent ->validate() call
28-
* @var ValidationError
29-
*/
30-
protected $error = null;
31-
3227
/**
3328
* As needed, build a validator in memory that knows how to load schema from local disk.
3429
* @return Validator
@@ -59,12 +54,25 @@ protected function getValidator(): Validator
5954
* @return bool
6055
*/
6156
public function validate($data, $schema): bool
57+
{
58+
$result = $this->validationResult($data, $schema);
59+
return $result->isValid();
60+
}
61+
62+
/**
63+
* Given data (could be a JsonModel, associative-array style JSON, primitive)
64+
* and a schema (could be a URI, an object literal, a JSON-encoded string)
65+
* return the ValidationResult of the upstream Opis library.
66+
* This is a good approach for methods that want to do their own error formatting through a deeper relationship with Opis
67+
* @param mixed $data
68+
* @param mixed $schema
69+
* @return ValidationResult
70+
*/
71+
public function validationResult($data, $schema): ValidationResult
6272
{
6373
$validator = $this->getValidator();
6474
$data = $this->normalizeData($data);
65-
$result = $validator->validate($data, $schema);
66-
$this->error = $result->error();
67-
return $result->isValid();
75+
return $validator->validate($data, $schema);
6876
}
6977

7078
/**
@@ -80,28 +88,6 @@ private function normalizeData($data)
8088
return json_decode(json_encode($data, JSON_THROW_ON_ERROR));
8189
}
8290

83-
/**
84-
* Return an array of errors from the last *Validation call
85-
* @return ValidationError|null
86-
*/
87-
public function getError(): ?ValidationError
88-
{
89-
return $this->error;
90-
}
91-
92-
/**
93-
* Return an array of human readable errors from the last *Validation call
94-
* @return array
95-
*/
96-
public function getFormattedError(): array
97-
{
98-
if (!$this->error) {
99-
return [];
100-
}
101-
102-
return (new ErrorFormatter())->formatFlat($this->error);
103-
}
104-
10591
/**
10692
* This method will attempt to validate the provided data against the provided schema. If the data is found to be
10793
* invalid, then a `JsonSchemaValidationException` exception is thrown with a default message of "Request body
@@ -122,23 +108,24 @@ public function validateOrThrow(
122108
bool $appendValidationDescriptions = false,
123109
int $failureHttpStatusCode = Response::HTTP_BAD_REQUEST,
124110
): bool {
125-
if ($this->validate($data, $schema) === false) {
111+
$results = $this->validationResult($data, $schema);
112+
if ($results->isValid() === false) {
126113
$message = $exceptionMessage ?: 'Request body contains invalid data!';
127114

128115
if ($appendValidationDescriptions) {
129116
$prepend = "\r\n* ";
130-
$message .= $prepend . implode($prepend, $this->getFormattedError());
117+
$message .= $prepend . implode($prepend, (new ErrorFormatter())->formatFlat($results->error()));
131118
}
132119

133120
Log::debug(
134121
"Json Schema Validation Error",
135122
[
136-
'error' => (new ErrorFormatter())->format($this->error, true, null, null),
123+
'error' => (new ErrorFormatter())->format($results->error(), true, null, null),
137124
'data' => $data
138125
]
139126
);
140127

141-
throw new JsonSchemaValidationException($message, $this->getError(), null, $failureHttpStatusCode);
128+
throw new JsonSchemaValidationException($message, $results->error(), null, $failureHttpStatusCode);
142129
}
143130

144131
return true;

app/Traits/JsonSchemaAssertions.php

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,18 @@ trait JsonSchemaAssertions
2222
* @param string $schemaUri
2323
* @param mixed $object
2424
* @param string $message
25-
* @param bool $addFormattedErrorToMessage
2625
* @return void
2726
*/
2827
public static function assertValidForSchema(
2928
string $schemaUri,
3029
$object,
3130
string $message = '',
32-
bool $addFormattedErrorToMessage = true,
3331
): void {
34-
$validates = SchemaValidator::validate($object, $schemaUri);
35-
36-
if ($addFormattedErrorToMessage) {
37-
$prepend = "\r\n* ";
38-
$message .= "\r\n" . $prepend . implode($prepend, SchemaValidator::getFormattedError());
32+
try {
33+
self::assertTrue(SchemaValidator::validate($object, $schemaUri), $message);
34+
} catch (JsonSchemaValidationException $e) {
35+
self::assertCanonicallySame([], $e->errors(), $message);
3936
}
40-
41-
static::assertThat($validates, static::isTrue(), $message);
4237
}
4338

4439
/**
@@ -65,6 +60,4 @@ public static function assertValid(CanValidate $model): void
6560
self::assertCanonicallySame([], $e->errors(), 'Validation failed with errors.');
6661
}
6762
}
68-
69-
7063
}

0 commit comments

Comments
 (0)