Problem/Motivation
I ran into a little issue with paragraphs where one of the paragraphs has a linkit-field (its widget extends the link field widget). When the user types in an invalid uri and then tries to add a new paragraph-item, an exception is preventing the new paragraph to be added.
One part of the problem is that the add-more button in paragraphs has a limit_validation_errors, so no validation is done or error is shown at all. I tried removing this, but that didn't work properly: it would validate the whole form and show error-messages in a way that's confusing for the user. After a bit of digging, I found that the error is an exception thrown when trying to make an Url-object from the invalid uri. So after adding a try/catch, it works fine :)
I think the problem is because the form is rebuilt without proper validation. In this case, the link-field considers the default value to be validated and tries to build a url-object out of the value. This fails, because the value is not a valid uri.
Steps to reproduce
- requires the paragraphs module
- setup a node type that has a paragraph field, which has a link-field
- go to the node-add form
- type in an invalid uri: just some random letters is fine
- press the button to add another paragraph item
- no error is shown, and also no new paragraph-item is added: the exception is in the log
Alternate steps:
- Install Drupal with standard profile
- Add link field (machine name: field_link) to Article content type. Allow both internal and external URLs.
- Use some method (e.g. migration, cli) other than the node form to create and save Article node with an invalid URL. Such as using Drush:
drush php-eval "Drupal::entityTypeManager()->getStorage('node')->create(['type' => 'article', 'title' => 'test', 'field_link' => ['uri' => 'www.example.com']])->save();" - Update `content_editor` role permissions and make sure:
- content editor has permission to edit any Article content
- content editor does not have permission to link to any page
- Create a new user and assign content editor role
- Log in as content editor
- Go to edit the node and observe:
The website encountered an unexpected error. Try again later. InvalidArgumentException: The URI 'www.example.com' is invalid. You must use a valid URI scheme. in Drupal\Core\Url::fromUri() (line 293 of core/lib/Drupal/Core/Url.php). Drupal\link\Plugin\Field\FieldType\LinkItem->getUrl() (Line: 194) Drupal\link\Plugin\Field\FieldWidget\LinkWidget->formElement(Object, 0, Array, Array, Object) (Line: 440) Drupal\Core\Field\WidgetBase->formSingleElement(Object, 0, Array, Array, Object) (Line: 210) Drupal\Core\Field\WidgetBase->formMultipleElements(Object, Array, Object) (Line: 111) Drupal\Core\Field\WidgetBase->form(Object, Array, Object) (Line: 186) Drupal\Core\Entity\Entity\EntityFormDisplay->buildForm(Object, Array, Object) (Line: 121) Drupal\Core\Entity\ContentEntityForm->form(Array, Object) (Line: 127) Drupal\node\NodeForm->form(Array, Object) (Line: 107) Drupal\Core\Entity\EntityForm->buildForm(Array, Object) call_user_func_array(Array, Array) (Line: 536) Drupal\Core\Form\FormBuilder->retrieveForm('node_article_edit_form', Object) (Line: 283) Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 73) Drupal\Core\Controller\FormController->getContentResult(Object, Object) call_user_func_array(Array, Array) (Line: 123) Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 591) Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124) Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97) Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 182) Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 76) Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58) Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106) Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85) Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48) Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 51) Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object, 1, 1) (Line: 704) Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Proposed resolution
Add a try/catch around getting the url-object.
Remaining tasks
Add tests
User interface changes
-
API changes
-
Data model changes
-
Release notes snippet
Issue fork drupal-3340154
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
spadxiii commentedComment #4
cilefen commentedWhat is the precise exception type?
Is this something Paragraphs should fix?
Can we get the stack trace please?
Comment #5
godotislatePut in a MR comment. This will also needs tests.
This is actually a similar to issue to #2745179: Uncaught exception in link formatter if a link field has malformed data, in that if malformed data is entered into the link field (via migration or otherwise), an exception will be thrown (though only if the user does not have "link to any page" permissions).
Comment #7
godotislateUpdated MR against 11.x and added a test.
Comment #8
godotislateComment #9
godotislateComment #10
smustgrave commentedUsing the fancy new test-only runner https://git.drupalcode.org/issue/drupal-3340154/-/jobs/148001 confirmed the test fails as expect
But manually testing I followed the steps in the IS
Install Drupal with standard profile
Add link field (field_link) to Article content type. Allow both internal and external URLs.
Use some method (e.g. migration, cli) other than the node form to create and save Article node with an invalid URL. Such as using Drush: drush php-eval "Drupal::entityTypeManager()->getStorage('node")->create(['type' => 'article', 'title' => 'test', 'field_link' => ['uri' => 'www.example.com']])->save();
Go to edit the node and observe:
And I don't get any error.
Comment #11
godotislateForgot: you have to log in as someone who does not have "link to any page" permission. Updated steps.
Comment #12
godotislateComment #13
godotislateComment #14
smustgrave commentedAh that was the missing step.
Comment #18
larowlanCommitted to 11.x and backported to 10.2.x
Thanks folks
Unpostponed the follow-up