Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Form] TransformationFailedException is swallowed #9989

Closed
davidkalosi opened this issue Jan 9, 2014 · 9 comments
Closed

[Form] TransformationFailedException is swallowed #9989

davidkalosi opened this issue Jan 9, 2014 · 9 comments
Labels

Comments

@davidkalosi
Copy link

The thrown TransformationFailedException is swallowed by the form component
it is happening in the code block bellow

excerpt from Form.php starting at line 631

          $modelData = $this->normToModel($normData);
            $viewData = $this->normToView($normData);
        }
    } catch (TransformationFailedException $e) {
        // the exception is caught here and is not throw again 
        $this->synchronized = false;

        // If $viewData was not yet set, set it to $submittedData so that
        // the erroneous data is accessible on the form.
        // Forms that inherit data never set any data, because the getters
        // forward to the parent form's getters anyway.
        if (null === $viewData && !$this->config->getInheritData()) {
            $viewData = $submittedData;
        }
    }
@jameshalsall
Copy link
Contributor

This is correct. The $form->isSynchronized() method will return false, which indicates that there was an issue with transforming the data.

Here it is in the API doc

@davidkalosi
Copy link
Author

OK I see I missed that ...
Anyway if this is the correct behaviour then it might be worth mentioning it in the cookbook section How to use Data Transformers since the article is quite misleading at the moment.

@davidkalosi
Copy link
Author

Looking at the code there is another issue with this approach - code taken from the cookbok.

If I would need to report any details from the failing transformation as in this example the only thing I can determine is that if failed which is $form->isSynchronized() but the error message is gone since the exception is thrown away

public function reverseTransform($number)
    {
        if (!$number) {
            return null;
        }

        $issue = $this->om
            ->getRepository('AcmeTaskBundle:Issue')
            ->findOneBy(array('number' => $number))
        ;

        if (null === $issue) {
            throw new TransformationFailedException(sprintf(
                'An issue with number "%s" does not exist!',
                $number
            ));
        }

        return $issue;
    }

@jameshalsall
Copy link
Contributor

In the event that transformation fails, the form is designed to fail gracefully and display the non transformed version of the data in the output.

cc / @bschussek

@davidkalosi
Copy link
Author

In my use case the transformation is relevant and it's vital that it succeeds.
Here is a description of what I am doing -
The form is used to transform incoming data (REST API) into command objects.
In our API we do reference some data through their URL for example when creating a new address the country name is from a lookup table that has it's own REST api and the create address has a json like this

{
    "addressLine1": "foobar",
    "country":"http://api.server.com/references/countries/uuid"
}

I have a service resolver that translates the URL into a subrequest in symfony and returns the UUID of the resource if it's valid otherwise it should fail and I should be able to send a message to the client that the entered country is not valid. the command object and the end of the form expects uuids not URLs.

maybe a sort of $form->getTransformationErrors() method would usefull or something similar.

@Tobion
Copy link
Member

Tobion commented Jan 10, 2014

Transformation errors will result in a general "Invalid value" error message.

@egeloen
Copy link

egeloen commented Jan 10, 2014

IMO, it is related to #9891

@davidkalosi
Copy link
Author

Here is another use case that comes to my mind - let's start again with the transfomer example that is supposed to return an issue. We can have a form for example that creates a new work log that as an issue field.
Suppose we would like to use 'empty_data' for initialization

class WorkLog {
   function __construct($comment, Issue $issue) {
       .............
   }
}

then in the form this will fail because issue is not initialized and this happens before you have a chance to
check for any errors

$resolver->setDefaults(array(
        'empty_data' => function (FormInterface $form) {
            return new WorkLog($form->get('comment')->getData(),
                                           $form->get('issue')->getData());
        },
    ));

@Tobion
Copy link
Member

Tobion commented Jan 10, 2014

Closing as duplicate of #9891 and #5607

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants