Skip to content

Commit

Permalink
Option to throw exceptions when an error is encountered (#354)
Browse files Browse the repository at this point in the history
* Add option to throw an exception on validation errors

* Update README

 * Changes API references to use the new Validator::validate() entry point
 * Adds section describing available config options
  • Loading branch information
erayd authored and bighappyface committed Feb 16, 2017
1 parent 9b6ebfe commit 7eb38e2
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 11 deletions.
45 changes: 34 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ $data = json_decode(file_get_contents('data.json'));

// Validate
$validator = new JsonSchema\Validator;
$validator->check($data, (object)['$ref' => 'file://' . realpath('schema.json')]);
$validator->validate($data, (object)['$ref' => 'file://' . realpath('schema.json')]);

if ($validator->isValid()) {
echo "The supplied JSON validates against the schema.\n";
Expand Down Expand Up @@ -63,22 +63,31 @@ $request = (object)[
'refundAmount'=>"17"
];

$validator->coerce($request, (object) [
$validator->validate(
$request, (object) [
"type"=>"object",
"properties"=>(object)[
"processRefund"=>(object)[
"type"=>"boolean"
],
"refundAmount"=>(object)[
"type"=>"number"
"properties"=>(object)[
"processRefund"=>(object)[
"type"=>"boolean"
],
"refundAmount"=>(object)[
"type"=>"number"
]
]
]
]); // validates!
],
Constraint::CHECK_MODE_COERCE_TYPES
); // validates!

is_bool($request->processRefund); // true
is_int($request->refundAmount); // true
```

A shorthand method is also available:
```PHP
$validator->coerce($request, $schema);
// equivalent to $validator->validate($data, $schema, Constraint::CHECK_MODE_COERCE_TYPES);
```

### With inline references

```php
Expand Down Expand Up @@ -130,9 +139,23 @@ $jsonValidator = new Validator( new Factory($schemaStorage));
$jsonToValidateObject = json_decode('{"data":123}');

// Do validation (use isValid() and getErrors() to check the result)
$jsonValidator->check($jsonToValidateObject, $jsonSchemaObject);
$jsonValidator->validate($jsonToValidateObject, $jsonSchemaObject);
```

### Configuration Options
A number of flags are available to alter the behavior of the validator. These can be passed as the
third argument to `Validator::validate()`, or can be provided as the third argument to
`Factory::__construct()` if you wish to persist them across multiple `validate()` calls.

| Flag | Description |
|------|-------------|
| `Constraint::CHECK_MODE_NORMAL` | Validate in 'normal' mode - this is the default |
| `Constraint::CHECK_MODE_TYPE_CAST` | Enable fuzzy type checking for associative arrays and objects |
| `Constraint::CHECK_MODE_COERCE_TYPES` | Convert data types to match the schema where possible |
| `Constraint::CHECK_MODE_EXCEPTIONS` | Throw an exception immediately if validation fails |

Please note that using `Constraint::CHECK_MODE_COERCE_TYPES` will modify your original data.

## Running the tests

```bash
Expand Down
5 changes: 5 additions & 0 deletions src/JsonSchema/Constraints/BaseConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace JsonSchema\Constraints;

use JsonSchema\Entity\JsonPointer;
use JsonSchema\Exception\ValidationException;

/**
* A more basic constraint definition - used for the public
Expand Down Expand Up @@ -47,6 +48,10 @@ public function addError(JsonPointer $path = null, $message, $constraint = '', a
'constraint' => $constraint,
);

if ($this->factory->getConfig(Constraint::CHECK_MODE_EXCEPTIONS)) {
throw new ValidationException(sprintf("Error validating %s: %s", $error['pointer'], $error['message']));
}

if (is_array($more) && count($more) > 0)
{
$error += $more;
Expand Down
1 change: 1 addition & 0 deletions src/JsonSchema/Constraints/Constraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ abstract class Constraint extends BaseConstraint implements ConstraintInterface
const CHECK_MODE_TYPE_CAST = 0x00000002;
const CHECK_MODE_COERCE_TYPES = 0x00000004;
const CHECK_MODE_APPLY_DEFAULTS = 0x00000008;
const CHECK_MODE_EXCEPTIONS = 0x00000010;

/**
* Bubble down the path
Expand Down
14 changes: 14 additions & 0 deletions src/JsonSchema/Exception/ValidationException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

/*
* This file is part of the JsonSchema package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace JsonSchema\Exception;

class ValidationException extends RuntimeException
{
}
52 changes: 52 additions & 0 deletions tests/Constraints/ValidationExceptionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

/*
* This file is part of the JsonSchema package.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace JsonSchema\Tests\Constraints;

use JsonSchema\Validator;
use JsonSchema\Constraints\Constraint;
use JsonSchema\Exception\ValidationException;

class ValidationExceptionTest extends \PHPUnit_Framework_TestCase
{
public function testValidationException()
{
$exception = new ValidationException();
$this->assertInstanceOf('\JsonSchema\Exception\ValidationException', $exception);

$checkValue = json_decode('{"propertyOne": "thisIsNotAnObject"}');
$schema = json_decode('{
"type": "object",
"additionalProperties": false,
"properties": {
"propertyOne": {
"type": "object"
}
}
}');

$validator = new Validator();

try {
$validator->validate($checkValue, $schema, Constraint::CHECK_MODE_EXCEPTIONS);
} catch (\Exception $e) {
$exception = $e;
}

$this->assertEquals(
'Error validating /propertyOne: String value found, but an object is required',
$exception->getMessage()
);


$this->setExpectedException('JsonSchema\Exception\ValidationException');
throw $exception;

}
}

0 comments on commit 7eb38e2

Please sign in to comment.