Problem/Motivation
I created a custom module with a blank "description" in the modules .info.yml file.
Trying to visit the Extend / module list page shows "The website encountered an unexpected error. Please try again later." and an error in the Watchdog log:
InvalidArgumentException: $string ("") must be a string. in Drupal\Core\StringTranslation\TranslatableMarkup->__construct() (line 140 of core/lib/Drupal/Core/StringTranslation/TranslatableMarkup.php)
The problem originates at line 209 in core/modules/system/src/Form/ModulesListForm.php
$row['description']['#markup'] = $this->t($module->info['description']);
Proposed solution is to test for $module-info['description']):
$row['description']['#markup'] = $this->t(isset($module->info['description']) ? $module->info['description'] : '');
There might be a better way, e.g. to highlight the missing description before we get to this point, or disable the module. According to https://www.drupal.org/node/2000204 the description should be required/mandatory.
Steps to reproduce
To reproduce, create an empty module with just a module info.yml as shown below, and visit the Extend page.
name : emptytest
description :
type: module
core : 8.xProposed resolution
See suggestion in #23
Remaining tasks
Agree on the solution
patch with test
review
commit
User interface changes
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #45 | 2730807-45.patch | 2.26 KB | lendude |
| #42 | 2730807-42-TEST_ONLY.patch | 1.46 KB | lendude |
| #41 | 2730807-41-TEST_ONLY.patch | 1.46 KB | lendude |
| #16 | cannot_view_module_list-2730807-16.patch | 739 bytes | cilefen |
| #2 | blankdescription-2730807-1.patch | 782 bytes | versantus.nik |
Comments
Comment #2
versantus.nik commentedComment #3
versantus.nik commentedComment #4
versantus.nik commentedComment #5
versantus.nik commentedMarking as Needs Review. Apologies for all of the accidental updates!
Comment #7
cilefen commentedComment #8
versantus.nik commentedComment #9
versantus.nik commentedComment #10
cilefen commentedUsually we add a test for something like this.
Comment #11
versantus.nik commentedThanks, I will have a go! I think I need to write a Functional Test (based on https://api.drupal.org/api/drupal/core%21core.api.php/group/testing/8.1.x). Do you agree?
Comment #12
cilefen commentedTry not to write a new test class. The test for the form you modified is Drupal\system\Tests\Form\ModulesListFormWebTest. Other places are Drupal\KernelTests\Core\Extension\ModuleInstallerTest or Drupal\system\Tests\Module\InstallUninstallTest. But in thinking about the patch in #2, it fixes this superficially (and I don't mean that negatively) in the UI, but if a module were enabled any other way, this would still be a problem. So in addition to a test I think we need a deeper fix. I think something at the level of module discovery would be better.
Comment #13
cilefen commentedComment #14
cilefen commentedThemeHandler::rebuildThemeData() has a way of merging defaults. I wonder if we can do something analogous for modules.
Comment #15
cilefen commented_system_rebuild_module_data() is supposed to do this but does not.
Comment #16
cilefen commentedThis is what I meant by "deeper" in #12. However, I now realize that #2 is probably more appropriate because the form function itself is calling t() on something that may be null and that is probably its problem.
In a case like this we are talking about valid YAML with description set, but empty, which means null. It seems other parts of Drupal don't have a problem with this. But notice that the defaults array in _system_rebuild_module_data() specifies that description is an empty string, assuming it was unset.
Comment #17
cilefen commentedComment #18
SidneyGijzen commentedGreat to see that there are already multiple approaches to solving this!
Reading through this issue and your patches, I was thinking along the following lines:
So, I'm wondering, does it make sense to add the description as a required key in getRequiredKeys()? Does that achieve that 'deeper fix' cilefen is looking for? And catches the error if the module is enabled in a non-GUI way?
Comment #19
cilefen commented@MF82: While we think about this, would you like to try writing the test? You can ping me on IRC for tips.
Comment #20
SidneyGijzen commented@cilefen: Yes, I would like to give it a try. I will first do some digging based on your pointers from #12. And, thank you!
Comment #21
almaudoh commentedI think a more generic solution for all .info.yml files where required keys are missing would be to throw a
MissingRequiredInfoKeyException(or some such) which could be caught and properly displayed on the UI.Comment #22
xjm@almaudoh, I think that's a good suggestion generally. I posted your suggestion on #2558645: Malformed module.info.yml prevents install with a confusing error because I think that's the correct solution for required keys.
In this case though it's not a required key, but an incorrectly empty optional key. In #2594937: Empty 'libraries:' in theme .info.yml file produces confusing PHP warning, there is a case to support the key being present but empty for DX/TX reasons.
I also agree that it's non-ideal to go though and add
isset()/!empty()checks all over the place for every individual, optional key.Comment #23
alexpottSo both modules and themes have a default array to merge to the information in .info.yml - see _system_rebuild_module_data() and \Drupal\Core\Extension\ThemeHandler::rebuildThemeData(). I think it is worth considering that if the yaml value is NULL we should use the default. That would fix both #2730807: WSOD on admin/modules if description is set but is NULL in module.info.yml and #2594937: Empty 'libraries:' in theme .info.yml file produces confusing PHP warning
Comment #24
xjmSo I guess it might be best to postpone this issue on that followup, which would also remove the then-redundant emptiness checks for individual keys?
Comment #29
jhedstromMarking as postponed as suggested above. Also a test is still needed if this approach is eventually pursued.
Comment #34
quietone commentedClosed #3243208: Empty description in a custom module info.yml leads to WSOD as a duplicate, Adding credit.
Comment #35
quietone commentedComment #36
danflanagan8This issue is still present in 9.4.x. But there's been some serious refactoring in core since the last patch here.For example,
_system_rebuild_module_datano longer exists.Following the pattern of the related issue, which adds a little check to
ThemeHandler::addTheme(), we could add a check toModuleHandler::addModule()that does something special when the description is null.However, the same WSOD occurs on the Appearance page if the description of a Theme is set to
null. If we wanted to fix both of these at the same time I would be in favor of that. (edit: here's an issue for the appearances WSOD: #3213079: When creating a theme, if you leave the description field empty in the themename.info.yml file, it throws a white screen error)In a comment on the related issue a follow-up was eluded to, but I don't think it was ever made. Comment #24 here even refers to "that followup", but I don't see any evidence that followup was created. From an issue queue standpoint, how should we proceed? Do we adjust this one to act as the followup? Do we close this and create a new issue from scratch?
From a code standpoint, we have some nice options.
We could add a check to
Drupal\Core\Extension\InfoParserDynamic::parse(), which is used for parsing module, theme, and profile .info files.But I think I like @alexpott's idea in #23 a little better though, which is to leverage the default values of the ExtensionList classes better. We could alter
ExtensionList::createExtensionInfo()to be more clever with the default values. The current code is below. It adds default values if the keys are missing, but it won't overwrite a value of null.There could be some simple code before the merge to unset any keys where the value is null. Then the default values would get used in those cases.
Update: But there's even another issue I found that wants to handle null values in TranslatableMarkup: #2719553: Log error when a TranslatableMarkup is created with a non-string input, which would make this issue moot.
Comment #41
lendudeThis seems to have gotten fixed in the intervening years, this test should be green
Comment #42
lendudeAh wait, not fixed, it has to be NULL to fail, see test
Comment #43
lendudeAh wait, not fixed, it has to be NULL to fail, see test
Comment #45
lendudeHere is a fix that implements #23, no interdiff since its a different approach than previously
Comment #46
lendudeIf we feel this is a good fix, we can close #3213079: When creating a theme, if you leave the description field empty in the themename.info.yml file, it throws a white screen error too
Comment #47
smustgrave commentedSo the IS points to #21 which is to throw a MissingRequiredInfoKeyException but is it now just to display a message?
Comment #48
lendudeWe can't/shouldn't throw an exception for description as if it is required, because it's not required. So the solution is now to make sure the defaults are used if something is set to NULL. I removed #21 from the IS.
Comment #49
smustgrave commentedGotcha.
Verified the problem described in the IS
Edited the action module description to be
description:Got a fatal error
Applied patch #45 and no issue now.
Comment #52
catchCommitted/pushed to 11.x and cherry-picked to 10.1.x, thanks!
Comment #53
lendudeThanks! I forgot to tag with ddd23, fixing that now.