diff --git a/Definition/BaseNode.php b/Definition/BaseNode.php index 099da4b39..1f7abfe74 100644 --- a/Definition/BaseNode.php +++ b/Definition/BaseNode.php @@ -104,6 +104,26 @@ public function getInfo() return $this->getAttribute('info'); } + /** + * Sets an error message. + * + * @param string $errorMessage + */ + public function setErrorMessage($errorMessage) + { + $this->setAttribute('errorMessage', $errorMessage); + } + + /** + * Returns error message. + * + * @return string The error message + */ + public function getErrorMessage() + { + return $this->getAttribute('errorMessage'); + } + /** * Sets the example configuration for this node. * diff --git a/Definition/Builder/NodeDefinition.php b/Definition/Builder/NodeDefinition.php index 614ceff3f..1e9010402 100644 --- a/Definition/Builder/NodeDefinition.php +++ b/Definition/Builder/NodeDefinition.php @@ -76,6 +76,17 @@ public function info($info) return $this->attribute('info', $info); } + /** + * Sets error message. + * + * @param string $errorMessage The error message text + * @return NodeDefinition + */ + public function errorMessage($errorMessage) + { + return $this->attribute('errorMessage', $errorMessage); + } + /** * Sets example configuration. * diff --git a/Definition/ScalarNode.php b/Definition/ScalarNode.php index 51141c42e..67aa345e6 100644 --- a/Definition/ScalarNode.php +++ b/Definition/ScalarNode.php @@ -34,11 +34,17 @@ class ScalarNode extends VariableNode protected function validateType($value) { if (!is_scalar($value) && null !== $value) { - $ex = new InvalidTypeException(sprintf( + $errorMessage = $this->getErrorMessage(); + $finalMessage = sprintf( 'Invalid type for path "%s". Expected scalar, but got %s.', $this->getPath(), gettype($value) - )); + ); + if ($errorMessage != null) { + $finalMessage .= sprintf("\nError message: %s.", $errorMessage); + } + + $ex = new InvalidTypeException($finalMessage); $ex->setPath($this->getPath()); throw $ex; diff --git a/Definition/VariableNode.php b/Definition/VariableNode.php index 69dfea6d8..e9970dffb 100644 --- a/Definition/VariableNode.php +++ b/Definition/VariableNode.php @@ -83,11 +83,17 @@ protected function validateType($value) protected function finalizeValue($value) { if (!$this->allowEmptyValue && empty($value)) { - $ex = new InvalidConfigurationException(sprintf( + $errorMessage = $this->getErrorMessage(); + $finalMessage = sprintf( 'The path "%s" cannot contain an empty value, but got %s.', $this->getPath(), json_encode($value) - )); + ); + if ($errorMessage != null) { + $finalMessage .= sprintf("\nError message: %s.", $errorMessage); + } + + $ex = new InvalidConfigurationException($finalMessage); $ex->setPath($this->getPath()); throw $ex; diff --git a/Tests/Definition/Builder/TreeBuilderTest.php b/Tests/Definition/Builder/TreeBuilderTest.php index ca2b0e637..4f6508c6e 100644 --- a/Tests/Definition/Builder/TreeBuilderTest.php +++ b/Tests/Definition/Builder/TreeBuilderTest.php @@ -124,4 +124,21 @@ public function testDefinitionExampleGetsTransferedToNode() $this->assertTrue(is_array($tree->getExample())); $this->assertEquals('example', $children['child']->getExample()); } + + public function testDefinitionErrorMessageGetsTransferedToNode() + { + $builder = new TreeBuilder(); + + $builder->root('test')->errorMessage('You are missing the root node') + ->children() + ->node('child', 'variable')->errorMessage('child error message')->defaultValue('default') + ->end() + ->end(); + + $tree = $builder->buildTree(); + $children = $tree->getChildren(); + + $this->assertEquals('You are missing the root node', $tree->getErrorMessage()); + $this->assertEquals('child error message', $children['child']->getErrorMessage()); + } } diff --git a/Tests/Definition/ScalarNodeTest.php b/Tests/Definition/ScalarNodeTest.php index 91e47ef3e..1e517ef5e 100644 --- a/Tests/Definition/ScalarNodeTest.php +++ b/Tests/Definition/ScalarNodeTest.php @@ -57,4 +57,42 @@ public function getInvalidValues() array(new \stdClass()), ); } + + public function testNormalizeThrowsExceptionWithoutErrorMessage() + { + $value = array(array('foo' => 'bar')); + $node = new ScalarNode('test'); + + $expectedMessage = sprintf( + 'Invalid type for path "%s". Expected scalar, but got %s.', + $node->getPath(), + gettype($value) + ); + + $this->setExpectedException( + 'Symfony\Component\Config\Definition\Exception\InvalidTypeException', $expectedMessage + ); + + $node->normalize($value); + } + + public function testNormalizeThrowsExceptionWithErrorMessage() + { + $value = array(array('foo' => 'bar')); + $node = new ScalarNode('test'); + $node->setErrorMessage('This is a custom error message'); + + $expectedMessage = sprintf( + 'Invalid type for path "%s". Expected scalar, but got %s.'. + "\nError message: ".$node->getErrorMessage(), + $node->getPath(), + gettype($value) + ); + + $this->setExpectedException( + 'Symfony\Component\Config\Definition\Exception\InvalidTypeException', $expectedMessage + ); + + $node->normalize($value); + } }