While working on a patch for Block Visibility Groups, I discovered a bug on the block list form (/admin/structure/block) of which I am not sure if it's a FAPI bug or a bug of this specific form:
When adding a Ajax-enabled button, and then in the ajax submit handler setting $form_state->setRebuild()
to have the form rebuilt, every second click on the button results in an internal server error, and every other click works completely fine.
To recreate apply attached patch, go to /admin/structure/block
, click the Test Ajax Rebuild button and see how the microtime for "Form was rebuilt on:" changes only every second time. Open up the network panel in web inspector to see that, for each clicks, responses alter between 200 OK and 500 Internal Server Error.
Will now try to debug.
Comment | File | Size | Author |
---|---|---|---|
#14 | 2567595-14.patch | 1.48 KB | quietone |
#2 | block_ajax-2.png | 320.71 KB | Frando |
#2 | block_ajax-1.png | 344.66 KB | Frando |
block_test_rebuild.patch | 1.38 KB | Frando | |
Comments
Comment #2
Frando CreditAttribution: Frando as a volunteer commentedI debugged this for quite some time.
So the problem is that on every second click, when it comes to the form rebuild, the EntityType object on the BlockListBuilder (which is the form's form builder) is an empty array instead of the EntityType object. The missing EntityType object fatals when trying to load the entity IDs.
I stepped through the whole thing with a debugger and compared the two alternating versions and thus could locate the point where the EntityType object gets lost. I totally do not understand this though.
See attached screenshots, for a successfull (first) and a failed Ajax request (second). Both are just clicks on the button with attached patch, on directly after the other.
When, in FormBuilder, getForm() invokes buildForm(), for the first run the entityType object is present on both the passed-in $form_arg and the callback_object property of $form_state. On the second run, its still present on the $form_arg property, but not anymore on the $form_state. More I could not find out, as I do not understand how the callback object gets set on the $form_state even on the successfull run - where does this happen?
I tried the test code from above patch on other forms and it worked fine for each click.
So here's the debugger screenshots:
First (successfull) request:
Second (failing) request:
Comment #3
Frando CreditAttribution: Frando as a volunteer commentedComment #14
quietone CreditAttribution: quietone at PreviousNext commentedI rerolled the test patch for Drupal 10.0.x, then applied the patch and tested. I was not able to reproduce the problem stated in the Issue Summary. The form was built on every click of the button.
Therefore, closing as cannot reproduce. If you are experiencing this problem on a supported version of Drupal reopen the issue, by setting the status to 'Active', and provide complete steps to reproduce the issue (starting from "Install Drupal core").
Thanks!