Problem/Motivation
Drupal\language\LanguageNegotiator::initializeType does not handle Drupal\Component\Plugin\Exception\PluginNotFoundException at all. If a language negotiation plugin was removed by mistake or uninstalled improperly, the whole Drupal site will fail. All drush command or page rendering would be stopped by the issue.
Proposed resolution
I think the negotiation process should handle a missing plugin more gracefully. It should either simply log the error with watchdog or display a message on frontend to prompt user to handle it. This should not have been a site breaking problem.
Add a messenger argument to language.services.yml to handle exception with plugin missing message.
Remaining tasks
Patch
Add test case
code review
User interface changes
None
API changes
None
Data model changes
None
Release notes snippet
None
| Comment | File | Size | Author |
|---|---|---|---|
| #57 | 3134349-57.patch | 4.33 KB | penyaskito |
Issue fork drupal-3134349
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 #2
yookoala commentedComment #3
yookoala commentedThese patches are the proposed changes to the language negotiator.
Comment #4
yookoala commentedIf these patches are in the right direction, I can also patch 9.0 and 9.1 development.
Comment #5
yookoala commentedComment #6
sharma.amitt16 commentedComment #7
sharma.amitt16 commentedReplaced the deprecated code.
Comment #8
sharma.amitt16 commentedComment #9
sharma.amitt16 commentedCorrection in the previous patch. Missed the modification in the service file to add messenger argument.
Comment #10
narendra.rajwar27Patch looks good to me since it is handling the language-negotiator plugin exception by adding messenger service to language service. Seems very appropriate way.
+1 RTBC
Comment #11
narendra.rajwar27Comment #12
narendra.rajwar27Comment #13
narendra.rajwar27Comment #14
freality commentedI think it's safe to state that a missing plugin should not collapse an entire system. If that's the case, I don't understand why it taken so long for this simple patch to be adopted into the codebase.
Consider this comment acknowledgement that the problem still exists and a vote to adopt this patch.
Comment #15
texas-bronius commentedThis is great! This is the sort of thing that makes us look as stable as a stable D8/D9 site is when properly working :)
Is there any use case where having the site completely crash with the uncaught exception might be the preferred route (ie: some chain of events that would follow that should never have occurred), or is this not our burden to consider?
Comment #16
joachim commentedThese whitespace changes are unrelated.
I'm not sure about outputting a message, which is a UI operation, in a service like this which is fairly deep. A watchdog error should be sufficient?
Comment #17
swatichouhan012 commented#16 1st point fixes, reverted unrelated whitespace changes.
Comment #21
s_leu commentedRe-roll for 9.5.x
Comment #23
smustgrave commentedThis issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.
As a bug this will need a test case.
Comment #24
sleitner commentedTest only patch.
Comment #25
sleitner commented#21 and #24 combined, please review
Comment #27
sleitner commentedComment #28
smustgrave commentedNew parameter should default to null with a trigger_error that it will be required in D11. Would search the repo for exact working. Then a simple unit or kernel test that when you pass null to the constructor you get that trigger_error response.
Also with a new parameter it will need a change record to announce this constructor now takes a new parameter.
Thanks
Comment #29
joachim commentedComment is too long, should be wrapped.
Also, we're not 'just logging the error' since we're also showing an error message.
If we're only testing the status, could this be done in a kernel test?
Comment #30
sleitner commentedPlease review, covers #28 and #29
Comment #31
penyaskitoWe use
everywhere in Drupal core. Change to that.
Nitpick: Put $messenger after $requestStack (before $currentUser and $negotiatedLanguages). I wouldn't be so nitpicky if I didn't have more feedback.
Same here. Use "The messenger"
The linked change record is unrelated. We need to create a draft one for the changes in this issue and link it here.
We can use \Drupal::logger() instead?
This test has no assertions.
I suggest:
+ We assert we don't have the exception we had until now.
+ We assert the message is shown.
+ We assert the error is logged.
I also tempt to agree with @joachim at #16. A visitor could see this error which is scary and he can't do anything about it. We might want to just log it.
Comment #32
sahil.goyal commentedAddressing the suggestions of #31 fixing these issues, Only point #4 is left as i not clear with it completely. Apart all issues being addresses in attached Patch with interdiffs. Leaving issue still in NW.
Comment #33
Vidushi Mehta commentedComment #34
smustgrave commentedWas mentioned in #32 that #31.4 has not been addressed.
Comment #35
sleitner commentedRemoved the messenger, just logs the error. No change record needed any more, because interface does not change.
Comment #36
penyaskito#35 looks close!
TIL :-)
I doubt this is the right assertion, as the exception would be thrown, not returned.
Can we upload a test-only patch to verify?
Comment #37
sleitner commentedI deleted the
assertNotInstanceOfComment #38
sleitner commentedComment #39
penyaskitoI'd prefer to assert by "The "Drupal\Tests\language\Kernel\LanguageNegotiatorPluginTest" plugin does not exist." but don't want to nitpick. Is RTBC for me.
Thanks for your work on this!
Comment #40
larowlanis assert false right here?
The comment says 'assert the error is logged'
but then we assertFalse?
Comment #41
penyaskitoMy bad, overlooked:
This needs to be language, not package_manager.
Also, even changing that didn't get it to work.
But
worked for me to fix the test.
As @larowlan pointed out, this needs to be assertTrue.
I'd change the string to 'The "Drupal\Tests\language\Kernel\LanguageNegotiatorPluginTest" plugin does not exist.' while we are there.
Comment #42
penyaskitoLet's also change the test to be explicit about the exception:
Comment #43
sleitner commentedIncludes issues of #39-#42
Comment #44
penyaskitoWe can call prophesize directly as you were doing. No need to include the trait.
We don't even need this line now that I see it, as it would fail on the initializeType method and we are not asserting on the switchLinks
Comment #45
akram khanaddress #44
Comment #46
akram khantry to fixed CCF #45
Comment #47
akram khanComment #48
penyaskitoLooks great now, all feedback was addressed. Thanks!
Comment #49
larowlanUpdating issue credits
Comment #52
larowlanremoved these out of scope whitespace changes on commit
Committed to 10.1.x and backported to 10.0.x
Will backport to 9.5.x if test run passes
Comment #54
larowlanReverted from 10.0.x as TestLogger does not exist there.
You could possibly use BufferingLogger instead
Comment #56
larowlanReverted from 10.1.x too, if we use BufferingLogger instead, we should have the same test in all three branches for consistency.
Comment #57
penyaskitoTook https://git.drupalcode.org/project/drupal/-/commit/b279c9946176bfc7a7dd5....
Changed TestLogger for BufferingLogger. Took as a reference
\Drupal\Tests\field\Kernel\EntityReference\EntityReferenceSettingsTestthat uses that class, but kept the changes to the minimum.As I just did what @larowlan said, I think this is small enough to RTBC it myself.
I've applied and run locally the test for 9.5.x, 10.0.x, 10.1.x, all green.
Comment #58
penyaskitoOne thing that I'm not sure how we operate with. There was a change record required at some point, and the draft was created. But it's not true anymore. Do we keep it as draft? Delete it? It can be confusing if we leave it as is.
Comment #62
larowlanCommitted to 10.1.x and backported to 10.0.x and 9.5.x
Deleted the change record