@@ -154,7 +154,7 @@ public function in($data, Context $options = null)
154
154
if ($ this ->__booleanSchema ) {
155
155
return $ data ;
156
156
} elseif (empty ($ options ->skipValidation )) {
157
- $ this ->fail (new InvalidValue ('Denied by false schema ' ), '# ' );
157
+ $ this ->fail (( new InvalidValue ('Denied by false schema ' ))-> withData ( $ data ), '# ' );
158
158
}
159
159
}
160
160
@@ -213,10 +213,10 @@ private function processType(&$data, Context $options, $path = '#')
213
213
$ valid = Type::isValid ($ this ->type , $ data , $ options ->version );
214
214
}
215
215
if (!$ valid ) {
216
- $ this ->fail (new TypeException (ucfirst (
216
+ $ this ->fail (( new TypeException (ucfirst (
217
217
implode (', ' , is_array ($ this ->type ) ? $ this ->type : array ($ this ->type ))
218
218
. ' expected, ' . json_encode ($ data ) . ' received ' )
219
- ), $ path );
219
+ ))-> withData ( $ data )-> withConstraint ( $ this -> type ) , $ path );
220
220
}
221
221
}
222
222
@@ -250,7 +250,9 @@ private function processEnum($data, $path = '#')
250
250
}
251
251
}
252
252
if (!$ enumOk ) {
253
- $ this ->fail (new EnumException ('Enum failed, enum: ' . json_encode ($ this ->enum ) . ', data: ' . json_encode ($ data )), $ path );
253
+ $ this ->fail ((new EnumException ('Enum failed, enum: ' . json_encode ($ this ->enum ) . ', data: ' . json_encode ($ data )))
254
+ ->withData ($ data )
255
+ ->withConstraint ($ this ->enum ), $ path );
254
256
}
255
257
}
256
258
@@ -274,10 +276,14 @@ private function processConst($data, $path)
274
276
$ diff = new JsonDiff ($ this ->const , $ data ,
275
277
JsonDiff::STOP_ON_DIFF );
276
278
if ($ diff ->getDiffCnt () != 0 ) {
277
- $ this ->fail (new ConstException ('Const failed ' ), $ path );
279
+ $ this ->fail ((new ConstException ('Const failed ' ))
280
+ ->withData ($ data )
281
+ ->withConstraint ($ this ->const ), $ path );
278
282
}
279
283
} else {
280
- $ this ->fail (new ConstException ('Const failed ' ), $ path );
284
+ $ this ->fail ((new ConstException ('Const failed ' ))
285
+ ->withData ($ data )
286
+ ->withConstraint ($ this ->const ), $ path );
281
287
}
282
288
}
283
289
}
@@ -299,7 +305,8 @@ private function processNot($data, Context $options, $path)
299
305
// Expected exception
300
306
}
301
307
if ($ exception === false ) {
302
- $ this ->fail (new LogicException ('Not ' . json_encode ($ this ->not ) . ' expected, ' . json_encode ($ data ) . ' received ' ), $ path . '->not ' );
308
+ $ this ->fail ((new LogicException ('Not ' . json_encode ($ this ->not ) . ' expected, ' . json_encode ($ data ) . ' received ' ))
309
+ ->withData ($ data ), $ path . '->not ' );
303
310
}
304
311
}
305
312
@@ -312,25 +319,29 @@ private function processString($data, $path)
312
319
{
313
320
if ($ this ->minLength !== null ) {
314
321
if (mb_strlen ($ data , 'UTF-8 ' ) < $ this ->minLength ) {
315
- $ this ->fail (new StringException ('String is too short ' , StringException::TOO_SHORT ), $ path );
322
+ $ this ->fail ((new StringException ('String is too short ' , StringException::TOO_SHORT ))
323
+ ->withData ($ data )->withConstraint ($ this ->minLength ), $ path );
316
324
}
317
325
}
318
326
if ($ this ->maxLength !== null ) {
319
327
if (mb_strlen ($ data , 'UTF-8 ' ) > $ this ->maxLength ) {
320
- $ this ->fail (new StringException ('String is too long ' , StringException::TOO_LONG ), $ path );
328
+ $ this ->fail ((new StringException ('String is too long ' , StringException::TOO_LONG ))
329
+ ->withData ($ data )->withConstraint ($ this ->maxLength ), $ path );
321
330
}
322
331
}
323
332
if ($ this ->pattern !== null ) {
324
333
if (0 === preg_match (Helper::toPregPattern ($ this ->pattern ), $ data )) {
325
- $ this ->fail (new StringException (json_encode ($ data ) . ' does not match to '
326
- . $ this ->pattern , StringException::PATTERN_MISMATCH ), $ path );
334
+ $ this ->fail ((new StringException (json_encode ($ data ) . ' does not match to '
335
+ . $ this ->pattern , StringException::PATTERN_MISMATCH ))
336
+ ->withData ($ data )->withConstraint ($ this ->pattern ), $ path );
327
337
}
328
338
}
329
339
if ($ this ->format !== null ) {
330
340
$ validationError = Format::validationError ($ this ->format , $ data );
331
341
if ($ validationError !== null ) {
332
342
if (!($ this ->format === "uri " && substr ($ path , -3 ) === ':id ' )) {
333
- $ this ->fail (new StringException ($ validationError ), $ path );
343
+ $ this ->fail ((new StringException ($ validationError ))
344
+ ->withData ($ data ), $ path );
334
345
}
335
346
}
336
347
}
@@ -345,55 +356,62 @@ private function processNumeric($data, $path)
345
356
{
346
357
if ($ this ->multipleOf !== null ) {
347
358
$ div = $ data / $ this ->multipleOf ;
348
- if ($ div != (int )$ div ) {
349
- $ this ->fail (new NumericException ($ data . ' is not multiple of ' . $ this ->multipleOf , NumericException::MULTIPLE_OF ), $ path );
359
+ if ($ div != (int )$ div && ($ div = $ data * (1 / $ this ->multipleOf )) && ($ div != (int )$ div )) {
360
+ $ this ->fail ((new NumericException ($ data . ' is not multiple of ' . $ this ->multipleOf , NumericException::MULTIPLE_OF ))
361
+ ->withData ($ data )->withConstraint ($ this ->multipleOf ), $ path );
350
362
}
351
363
}
352
364
353
365
if ($ this ->exclusiveMaximum !== null && !is_bool ($ this ->exclusiveMaximum )) {
354
366
if ($ data >= $ this ->exclusiveMaximum ) {
355
- $ this ->fail (new NumericException (
367
+ $ this ->fail (( new NumericException (
356
368
'Value less or equal than ' . $ this ->exclusiveMaximum . ' expected, ' . $ data . ' received ' ,
357
- NumericException::MAXIMUM ), $ path );
369
+ NumericException::MAXIMUM ))
370
+ ->withData ($ data )->withConstraint ($ this ->exclusiveMaximum ), $ path );
358
371
}
359
372
}
360
373
361
374
if ($ this ->exclusiveMinimum !== null && !is_bool ($ this ->exclusiveMinimum )) {
362
375
if ($ data <= $ this ->exclusiveMinimum ) {
363
- $ this ->fail (new NumericException (
376
+ $ this ->fail (( new NumericException (
364
377
'Value more or equal than ' . $ this ->exclusiveMinimum . ' expected, ' . $ data . ' received ' ,
365
- NumericException::MINIMUM ), $ path );
378
+ NumericException::MINIMUM ))
379
+ ->withData ($ data )->withConstraint ($ this ->exclusiveMinimum ), $ path );
366
380
}
367
381
}
368
382
369
383
if ($ this ->maximum !== null ) {
370
384
if ($ this ->exclusiveMaximum === true ) {
371
385
if ($ data >= $ this ->maximum ) {
372
- $ this ->fail (new NumericException (
386
+ $ this ->fail (( new NumericException (
373
387
'Value less or equal than ' . $ this ->maximum . ' expected, ' . $ data . ' received ' ,
374
- NumericException::MAXIMUM ), $ path );
388
+ NumericException::MAXIMUM ))
389
+ ->withData ($ data )->withConstraint ($ this ->maximum ), $ path );
375
390
}
376
391
} else {
377
392
if ($ data > $ this ->maximum ) {
378
- $ this ->fail (new NumericException (
393
+ $ this ->fail (( new NumericException (
379
394
'Value less than ' . $ this ->maximum . ' expected, ' . $ data . ' received ' ,
380
- NumericException::MAXIMUM ), $ path );
395
+ NumericException::MAXIMUM ))
396
+ ->withData ($ data )->withConstraint ($ this ->maximum ), $ path );
381
397
}
382
398
}
383
399
}
384
400
385
401
if ($ this ->minimum !== null ) {
386
402
if ($ this ->exclusiveMinimum === true ) {
387
403
if ($ data <= $ this ->minimum ) {
388
- $ this ->fail (new NumericException (
404
+ $ this ->fail (( new NumericException (
389
405
'Value more or equal than ' . $ this ->minimum . ' expected, ' . $ data . ' received ' ,
390
- NumericException::MINIMUM ), $ path );
406
+ NumericException::MINIMUM ))
407
+ ->withData ($ data )->withConstraint ($ this ->minimum ), $ path );
391
408
}
392
409
} else {
393
410
if ($ data < $ this ->minimum ) {
394
- $ this ->fail (new NumericException (
411
+ $ this ->fail (( new NumericException (
395
412
'Value more than ' . $ this ->minimum . ' expected, ' . $ data . ' received ' ,
396
- NumericException::MINIMUM ), $ path );
413
+ NumericException::MINIMUM ))
414
+ ->withData ($ data )->withConstraint ($ this ->minimum ), $ path );
397
415
}
398
416
}
399
417
}
@@ -445,13 +463,15 @@ private function processOneOf($data, Context $options, $path)
445
463
$ exception = new LogicException ('No valid results for oneOf { ' . "\n" . substr ($ failures , 0 , -1 ) . "\n} " );
446
464
$ exception ->error = 'No valid results for oneOf ' ;
447
465
$ exception ->subErrors = $ subErrors ;
466
+ $ exception ->data = $ data ;
448
467
$ this ->fail ($ exception , $ path );
449
468
} elseif ($ successes > 1 ) {
450
469
$ exception = new LogicException ('More than 1 valid result for oneOf: '
451
470
. $ successes . '/ ' . count ($ this ->oneOf ) . ' valid results for oneOf { '
452
471
. "\n" . substr ($ failures , 0 , -1 ) . "\n} " );
453
472
$ exception ->error = 'More than 1 valid result for oneOf ' ;
454
473
$ exception ->subErrors = $ subErrors ;
474
+ $ exception ->data = $ data ;
455
475
$ this ->fail ($ exception , $ path );
456
476
}
457
477
}
@@ -492,6 +512,7 @@ private function processAnyOf($data, Context $options, $path)
492
512
. "\n} " );
493
513
$ exception ->error = 'No valid results for anyOf ' ;
494
514
$ exception ->subErrors = $ subErrors ;
515
+ $ exception ->data = $ data ;
495
516
$ this ->fail ($ exception , $ path );
496
517
}
497
518
return $ result ;
@@ -554,7 +575,12 @@ private function processObjectRequired($array, Context $options, $path)
554
575
{
555
576
foreach ($ this ->required as $ item ) {
556
577
if (!array_key_exists ($ item , $ array )) {
557
- $ this ->fail (new ObjectException ('Required property missing: ' . $ item . ', data: ' . json_encode ($ array , JSON_UNESCAPED_SLASHES ), ObjectException::REQUIRED ), $ path );
578
+ $ this ->fail (
579
+ (new ObjectException (
580
+ 'Required property missing: ' . $ item . ', data: ' . json_encode ($ array , JSON_UNESCAPED_SLASHES ),
581
+ ObjectException::REQUIRED ))
582
+ ->withData ((object )$ array )->withConstraint ($ item ),
583
+ $ path );
558
584
}
559
585
}
560
586
}
@@ -780,10 +806,12 @@ private function processObject($data, Context $options, $path, $result = null)
780
806
781
807
if (!$ options ->skipValidation ) {
782
808
if ($ this ->minProperties !== null && count ($ array ) < $ this ->minProperties ) {
783
- $ this ->fail (new ObjectException ("Not enough properties " , ObjectException::TOO_FEW ), $ path );
809
+ $ this ->fail ((new ObjectException ("Not enough properties " , ObjectException::TOO_FEW ))
810
+ ->withData ($ data )->withConstraint ($ this ->minProperties ), $ path );
784
811
}
785
812
if ($ this ->maxProperties !== null && count ($ array ) > $ this ->maxProperties ) {
786
- $ this ->fail (new ObjectException ("Too many properties " , ObjectException::TOO_MANY ), $ path );
813
+ $ this ->fail ((new ObjectException ("Too many properties " , ObjectException::TOO_MANY ))
814
+ ->withData ($ data )->withConstraint ($ this ->maxProperties ), $ path );
787
815
}
788
816
if ($ this ->propertyNames !== null ) {
789
817
$ propertyNames = self ::unboolSchema ($ this ->propertyNames );
@@ -845,8 +873,9 @@ private function processObject($data, Context $options, $path, $result = null)
845
873
} else {
846
874
foreach ($ dependencies as $ item ) {
847
875
if (!array_key_exists ($ item , $ array )) {
848
- $ this ->fail (new ObjectException ('Dependency property missing: ' . $ item ,
849
- ObjectException::DEPENDENCY_MISSING ), $ path );
876
+ $ this ->fail ((new ObjectException ('Dependency property missing: ' . $ item ,
877
+ ObjectException::DEPENDENCY_MISSING ))
878
+ ->withData ($ data )->withConstraint ($ item ), $ path );
850
879
}
851
880
}
852
881
}
@@ -892,7 +921,8 @@ private function processObject($data, Context $options, $path, $result = null)
892
921
}
893
922
if (!$ found && $ this ->additionalProperties !== null ) {
894
923
if (!$ options ->skipValidation && $ this ->additionalProperties === false ) {
895
- $ this ->fail (new ObjectException ('Additional properties not allowed: ' . $ key ), $ path );
924
+ $ this ->fail ((new ObjectException ('Additional properties not allowed: ' . $ key ))
925
+ ->withData ($ data ), $ path );
896
926
}
897
927
898
928
if ($ this ->additionalProperties instanceof SchemaContract) {
@@ -968,11 +998,11 @@ private function processArray($data, Context $options, $path, $result)
968
998
$ count = count ($ data );
969
999
if (!$ options ->skipValidation ) {
970
1000
if ($ this ->minItems !== null && $ count < $ this ->minItems ) {
971
- $ this ->fail (new ArrayException ("Not enough items in array " ), $ path );
1001
+ $ this ->fail (( new ArrayException ("Not enough items in array " ))-> withData ( $ data ), $ path );
972
1002
}
973
1003
974
1004
if ($ this ->maxItems !== null && $ count > $ this ->maxItems ) {
975
- $ this ->fail (new ArrayException ("Too many items in array " ), $ path );
1005
+ $ this ->fail (( new ArrayException ("Too many items in array " ))-> withData ( $ data ), $ path );
976
1006
}
977
1007
}
978
1008
@@ -1007,26 +1037,26 @@ private function processArray($data, Context $options, $path, $result)
1007
1037
$ result [$ key ] = $ additionalItems ->process ($ value , $ options , $ path . '-> ' . $ pathItems
1008
1038
. '[ ' . $ index . ']: ' . $ index );
1009
1039
} elseif (!$ options ->skipValidation && $ additionalItems === false ) {
1010
- $ this ->fail (new ArrayException ('Unexpected array item ' ), $ path );
1040
+ $ this ->fail (( new ArrayException ('Unexpected array item ' ))-> withData ( $ data ), $ path );
1011
1041
}
1012
1042
}
1013
1043
++$ index ;
1014
1044
}
1015
1045
1016
1046
if (!$ options ->skipValidation && $ this ->uniqueItems ) {
1017
1047
if (!UniqueItems::isValid ($ data )) {
1018
- $ this ->fail (new ArrayException ('Array is not unique ' ), $ path );
1048
+ $ this ->fail (( new ArrayException ('Array is not unique ' ))-> withData ( $ data ), $ path );
1019
1049
}
1020
1050
}
1021
1051
1022
1052
if (!$ options ->skipValidation && $ this ->contains !== null ) {
1023
1053
/** @var Schema|bool $contains */
1024
1054
$ contains = $ this ->contains ;
1025
1055
if ($ contains === false ) {
1026
- $ this ->fail (new ArrayException ('Contains is false ' ), $ path );
1056
+ $ this ->fail (( new ArrayException ('Contains is false ' ))-> withData ( $ data ), $ path );
1027
1057
}
1028
1058
if ($ count === 0 ) {
1029
- $ this ->fail (new ArrayException ('Empty array fails contains constraint ' ), $ path );
1059
+ $ this ->fail (( new ArrayException ('Empty array fails contains constraint ' ) ), $ path );
1030
1060
}
1031
1061
if ($ contains === true ) {
1032
1062
$ contains = self ::unboolSchema ($ contains );
@@ -1041,7 +1071,8 @@ private function processArray($data, Context $options, $path, $result)
1041
1071
}
1042
1072
}
1043
1073
if (!$ containsOk ) {
1044
- $ this ->fail (new ArrayException ('Array fails contains constraint ' ), $ path );
1074
+ $ this ->fail ((new ArrayException ('Array fails contains constraint ' ))
1075
+ ->withData ($ data ), $ path );
1045
1076
}
1046
1077
}
1047
1078
return $ result ;
0 commit comments