Problem/Motivation
Back in #1993202: Convert system_modules_uninstall() to a Controller the module uninstall form and the corresponding confirm form were converted from a single form which switches itself out internally to a multi-step form using an expirable key-value entry. That entry has an expiration of 60 seconds. It was added to the patch over there originally (when it was still set to 120 seconds) with the comment
Time to expire is set to 2 minutes. This could be less because we only need it for the duration of the page request.
(The comment did not end up in the patch that got committed.)
The reasoning is wrong however. The key-value entry is set when the module uninstall form gets submitted and it gets read when the uninstall confirm form gets submitted. Thus, the uninstall confirm form essentially gets invalidated after 60 seconds. If you submit the uninstall confirm form then you just get redirected to the uninstall form again, without the module(s) having been uninstalled and without any error or message of any kind.
Especially in non-optimized environments the Drupal administration UI (and especially the modules form) can take quite a few seconds to load which can lead to people switching to another task until the page loading completes. Therefore, the expiration of this particular form is far more likely to hit people than other forms. Also people are not used to this behavior, because all other forms in Drupal expire only after 6 hours.
Thus, marking critical. (Seemingly) Not being able to uninstall modules makes Drupal critically broken. Since there is no warning message or anything there is no way for the user to figure out that time is running as soon the module uninstall confirm form loads.
Proposed resolution
?
Remaining tasks
User interface changes
API changes
Beta phase evaluation
| Issue category | Bug because modules cannot be uninstalled under certain circumstances |
|---|---|
| Issue priority | Major because users with low performance environments get the impression that uninstalling modules is impossible/broken or unreliable/sometimes broken. The modularity and the ability to uninstall modules is an essential part of Drupal and it must work without ifs or buts. |
| Comment | File | Size | Author |
|---|---|---|---|
| #21 | 2475715-21.patch | 3.13 KB | stefan.r |
| #18 | 2475715-18.patch | 3.24 KB | stefan.r |
| #16 | 2475715-16.patch | 3.03 KB | stefan.r |
| #16 | interdiff-10-16.txt | 1.47 KB | stefan.r |
| #10 | 2475715-10.patch | 2.55 KB | stefan.r |
Comments
Comment #1
xjmTo me this sounds major, since there is a workaround (reload the form). Icky bug though, and good find!
Comment #2
tstoecklerHow does reloading the form help?
Comment #3
tstoecklerMarking critical again, as it's not clear what the workaround is.
Note that the known "workaround" is submitting the form in less than 60 seconds but the problem is that it's not all clear that this is the case so it's very hard if not impossible to figure out the workaround if you do not find this issue on Drupal.org. That's why I don't think that can actually be considered a workaround with any meaningful definition of that word.
Comment #4
dawehnerGiven that the uninstall form is not like a super high frequent accessed page, I think it would be totally legit to increase the number,
but yeah I guess we should have some common pattern to show some form of message what was going on.
Comment #5
stefan.r commentedI guess the timeout could be set to 6 hours here as well, or even a week which is what we use in tempstore.
Just some ideas for the message (which we could maybe use on other forms as well):
a) ping the server when we're about to expire the data, setting the key/value expiry date into the future on every ping (though that won't work when there's no internet connection).
b) inform users on the confirmation form itself that they have X amount of time to press the confirm button (which may be confusing and raise more questions than it answers).
c) if users press the confirm button when the data is already expired, display a big red error screen that links back to the uninstall page.
d) prevent users from having a failed confirmation attempt in the first place, i.e. when they're about to time out we auto redirect them away from the confirmation page to a big red error page explaining what just happened
I would lean toward d) with a fallback to c) in case javascript breaks or the internet connection goes away, and just set the timeout to an as large as possible number so we don't have to show any unnecessary error screens anyway.
Comment #6
catchYes either that, or resubmitting the form.
It's definitely an annoying bug, but it doesn't prevent uninstalling modules altogether and it's not like an entity form where there's actual data loss. Per https://www.drupal.org/core/issue-priority this is definitely major for me.
Comment #7
dawehnerIt seems to be that we should set the time to a reasonable high value and be done with it ...
Comment #8
stefan.r commented@dawehner or even unreasonably high, as in a week? We use a week in tempstore as well...
Still, this needs an error message at least. Also the redirect didn't work when using a URL prefix.
Comment #10
stefan.r commentedLooks like Simpletest wants the redirect to be an absolute URL
Comment #13
tstoecklerSince the Form cache itself is only valid for 6 hours anyway, does it make sense to use that value here as well? Or am I mixing up different things?
Comment #14
stefan.r commentedMaybe someone else can confirm but I don't think this particular form is cached...
Comment #15
stefan.r commentedActually there is an additional problem with the uninstall form, it doesn't validate correctly.
If we submit an empty uninstall form, it will trigger the submit hooks despite an error happening in the validation. This is because the validation error is a simple drupal_set_message() as opposed to being filed against the form, so the
$form_state->setRedirect('system.modules_uninstall');gets overwritten by$form_state->setRedirect('system.modules_uninstall_confirm');in the submit hooks.The current issue is about bad things happening in the transition from the uninstall form to the uninstall confirm form as well, so we can probably add a fix for this to the patch?
Comment #16
stefan.r commentedSo just to summarize, the issues here were:
Comment #17
dawehnerGood idea
+1
Do we have that stored somewhere accessible in form cache? Should we also document why we hav chosen that particular value?
Comment #18
stefan.r commentedAdded a comment.
Comment #21
stefan.r commentedre-roll. Also set the expiration date to 6 hours, though not sure this form even uses the form cache?
Comment #22
dawehnerI guess no, but its still a fair number
Comment #25
stefan.r commentedRe-queued the patch for testing because of test fail unrelated to this patch (which also occurred on other issues):
"FAILED: [[SimpleTest]]: [PHP 5.4 MySQL] Repository checkout: failed to checkout from [git://git.drupal.org/project/drupal.git]."
Comment #26
stefan.r commentedBack to RTBC
Comment #27
alexpottCommitted 99e0777 and pushed to 8.0.x. Thanks!
Thanks for adding the beta evaluation to the issue summary.