From d56b7be156e66a9587d0a29dce7eb6c336838ffc Mon Sep 17 00:00:00 2001 From: jubianchi Date: Sat, 5 Jul 2014 16:13:07 +0200 Subject: [PATCH] [WIP][Form] Improve transformation failure message by providing property path --- src/Symfony/Component/Form/Form.php | 58 ++++++++++++++++--- .../Tests/Fixtures/FixedDataTransformer.php | 6 +- .../Component/Form/Tests/SimpleFormTest.php | 22 +++++++ 3 files changed, 74 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index 3e9f9b1058..6c893221ac 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -1049,12 +1049,22 @@ class Form implements \IteratorAggregate, FormInterface * * @param mixed $value The value to transform * + * @throws TransformationFailedException If the value cannot be transformed to "normalized" format + * * @return mixed */ private function modelToNorm($value) { - foreach ($this->config->getModelTransformers() as $transformer) { - $value = $transformer->transform($value); + try { + foreach ($this->config->getModelTransformers() as $transformer) { + $value = $transformer->transform($value); + } + } catch (TransformationFailedException $exception) { + throw new TransformationFailedException( + 'Unable to transform value for property path "' . $this->getPropertyPath() . '": ' . $exception->getMessage(), + $exception->getCode(), + $exception + ); } return $value; @@ -1065,14 +1075,24 @@ class Form implements \IteratorAggregate, FormInterface * * @param string $value The value to reverse transform * + * @throws TransformationFailedException If the value cannot be transformed to "model" format + * * @return mixed */ private function normToModel($value) { - $transformers = $this->config->getModelTransformers(); + try { + $transformers = $this->config->getModelTransformers(); - for ($i = count($transformers) - 1; $i >= 0; --$i) { - $value = $transformers[$i]->reverseTransform($value); + for ($i = count($transformers) - 1; $i >= 0; --$i) { + $value = $transformers[$i]->reverseTransform($value); + } + } catch (TransformationFailedException $exception) { + throw new TransformationFailedException( + 'Unable to reverse value for property path "' . $this->getPropertyPath() . '": ' . $exception->getMessage(), + $exception->getCode(), + $exception + ); } return $value; @@ -1083,6 +1103,8 @@ class Form implements \IteratorAggregate, FormInterface * * @param mixed $value The value to transform * + * @throws TransformationFailedException If the value cannot be transformed to "view" format + * * @return mixed */ private function normToView($value) @@ -1096,8 +1118,16 @@ class Form implements \IteratorAggregate, FormInterface return null === $value || is_scalar($value) ? (string) $value : $value; } - foreach ($this->config->getViewTransformers() as $transformer) { - $value = $transformer->transform($value); + try { + foreach ($this->config->getViewTransformers() as $transformer) { + $value = $transformer->transform($value); + } + } catch (TransformationFailedException $exception) { + throw new TransformationFailedException( + 'Unable to transform value for property path "' . $this->getPropertyPath() . '": ' . $exception->getMessage(), + $exception->getCode(), + $exception + ); } return $value; @@ -1108,6 +1138,8 @@ class Form implements \IteratorAggregate, FormInterface * * @param string $value The value to reverse transform * + * @throws TransformationFailedException If the value cannot be transformed to "normalized" format + * * @return mixed */ private function viewToNorm($value) @@ -1118,8 +1150,16 @@ class Form implements \IteratorAggregate, FormInterface return '' === $value ? null : $value; } - for ($i = count($transformers) - 1; $i >= 0; --$i) { - $value = $transformers[$i]->reverseTransform($value); + try { + for ($i = count($transformers) - 1; $i >= 0; --$i) { + $value = $transformers[$i]->reverseTransform($value); + } + } catch (TransformationFailedException $exception) { + throw new TransformationFailedException( + 'Unable to reverse value for property path "' . $this->getPropertyPath() . '": ' . $exception->getMessage(), + $exception->getCode(), + $exception + ); } return $value; diff --git a/src/Symfony/Component/Form/Tests/Fixtures/FixedDataTransformer.php b/src/Symfony/Component/Form/Tests/Fixtures/FixedDataTransformer.php index a5a31248f5..f7fba56c42 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/FixedDataTransformer.php +++ b/src/Symfony/Component/Form/Tests/Fixtures/FixedDataTransformer.php @@ -12,7 +12,7 @@ namespace Symfony\Component\Form\Tests\Fixtures; use Symfony\Component\Form\DataTransformerInterface; -use Symfony\Component\Form\Exception\RuntimeException; +use Symfony\Component\Form\Exception\TransformationFailedException; class FixedDataTransformer implements DataTransformerInterface { @@ -26,7 +26,7 @@ class FixedDataTransformer implements DataTransformerInterface public function transform($value) { if (!array_key_exists($value, $this->mapping)) { - throw new RuntimeException(sprintf('No mapping for value "%s"', $value)); + throw new TransformationFailedException(sprintf('No mapping for value "%s"', $value)); } return $this->mapping[$value]; @@ -37,7 +37,7 @@ class FixedDataTransformer implements DataTransformerInterface $result = array_search($value, $this->mapping, true); if ($result === false) { - throw new RuntimeException(sprintf('No reverse mapping for value "%s"', $value)); + throw new TransformationFailedException(sprintf('No reverse mapping for value "%s"', $value)); } return $result; diff --git a/src/Symfony/Component/Form/Tests/SimpleFormTest.php b/src/Symfony/Component/Form/Tests/SimpleFormTest.php index 11b616b1b3..6f2ffdd5cf 100644 --- a/src/Symfony/Component/Form/Tests/SimpleFormTest.php +++ b/src/Symfony/Component/Form/Tests/SimpleFormTest.php @@ -74,6 +74,28 @@ class SimpleFormTest extends AbstractFormTest $this->assertSame('bar', $form->getViewData()); } + /** + * @expectedException \Symfony\Component\Form\Exception\TransformationFailedException + * @expectedExceptionMessage Unable to transform value for property path "name": No mapping for value "arg" + */ + public function testDataTransformationFailure() + { + $model = new FixedDataTransformer(array( + 'default' => 'foo', + )); + $view = new FixedDataTransformer(array( + 'foo' => 'bar', + )); + + $config = new FormConfigBuilder('name', null, $this->dispatcher); + $config->addViewTransformer($view); + $config->addModelTransformer($model); + $config->setData('arg'); + $form = new Form($config); + + $form->getData(); + } + // https://github.com/symfony/symfony/commit/d4f4038f6daf7cf88ca7c7ab089473cce5ebf7d8#commitcomment-1632879 public function testDataIsInitializedFromSubmit() {