Deletion of view used by layout builder breaks page with custom layout built by layout builder.
Problem/Motivation
I did following.
- create some simple view block
- used it for layouting of single page (so configuration will be saved in field)
- delete view block
- open previously layouted page
And following exception is thrown:
TypeError: Argument 1 passed to Drupal\views\ViewExecutableFactory::get() must implement interface Drupal\views\ViewEntityInterface, null given, called in /var/www/html/core/modules/views/src/Plugin/Block/ViewsBlockBase.php on line 69 in Drupal\views\ViewExecutableFactory->get() (line 70 of core/modules/views/src/ViewExecutableFactory.php).
Drupal\views\ViewExecutableFactory->get(NULL) (Line: 69)
Drupal\views\Plugin\Block\ViewsBlockBase->__construct(Array, 'views_block:test-block_1', Array, Object, Object, Object) (Line: 84)
Proposed resolution
Maybe this is a bit conceptual problem with saving layout builder information as a serialized blob.
This is one case where the problem occurs, another possible case is when some module provides block and wants to update its configuration. How I see it, update hook should go over all layout fields -> load config -> check if there is a config for that particular block ->update it -> serialize again.
Comment | File | Size | Author |
---|---|---|---|
#15 | 2965973-15.patch | 9.78 KB | tedbow |
#15 | interdiff-12-15.txt | 0 bytes | tedbow |
#15 | 2965973-15-TEST_ONLY.patch | 7.65 KB | tedbow |
#12 | 2965973-12.patch | 9.78 KB | tedbow |
#12 | 2965973-12-test_only.patch | 2.25 KB | tedbow |
Comments
Comment #2
alexpottThis issue is at least major for layout builder and blocks a stable release.
Comment #3
tedbowIt seems like since basically we now have content that dependent on config then Layout Builder should handle missing plugins gracefully.
When a View block is deleted there could be thousands of nodes or other content entities that references this via serialized value.
Looking at how that would work.
Comment #4
tim.plunkettI can't reproduce this. Instead, the views block derivative goes missing and I get this message where the view was located:
which is not as ideal as being able to find and remove the view. But it's way less broken than the IS implies.
Comment #5
tedbowOne way to solve the hard error would be for Views to clear the block definitions cache in
\Drupal\views\Plugin\views\display\Block::remove
Instead you would see
Which seems better.
But it would also solve another problem which I don't think has another issue
Comment #6
tedbowRE #4 I am able to reproduce problem in the IS.
I will try to write test that proves it.
Comment #7
tedbowHere is rough test to prove that it fails.
Probably don't need
$assert_session->pageTextNotContains('Argument 1 passed to Drupal\views\ViewExecutableFactory::get() must implement interface Drupal\views\ViewEntityInterface');
but this proves the particular error for the issue.
Comment #9
tim.plunkettNice! Also thought about #2966969: Trigger a warning whenever the "Broken" block plugin is instantiated
Comment #10
lokapujyaWhat is the step is to reproduce the error manually? I also just see:
The test shows the error, but I can't see what's different about the automated test.
Comment #11
tim.plunkettOn my local, I have all caching disabled, which prevented me from reproducing since the fix is to clear caches at the right time :)
Comment #12
tedbowCleaning up the test.
Comment #14
lokapujyaYes, after turning on cache, I was able to reproduce the error.
I like the updated test better because it is more durable; it doesn't rely on the error message. Although the error message was helpful in the rough test for proving the problem.
Comment #15
tedbow@lokapujya thanks for catching that adding a new test only patch.
This permission is not needed so removing
Adding an assertion at the end to confirm the View is not on the page.
Comment #17
lokapujyaComment #19
larowlanAs this adds a new argument to the constructor of the views Block display plugin. I think it will be disruptive, I have sub-classed that plugin in custom projects a few times.
So I think that makes this 8.6 only, especially given it only surfaces in layout builder (experimental) and it can be resolved with a cache clear
Committed as ce1f1fc and pushed to 8.6.x.
Comment #21
tim.plunkettRetroactively tagging