Problem/Motivation

If you pass a completely invalid extension to LibraryDiscoveryParser::buildByExtension() it just assumes it's a theme. This results in php notices when trying to load the libraries.yml file and similar.

Proposed resolution

Provide a more useful error message, ideally throw an exception if we don't think it's breaking bc to do so.

Remaining tasks

User interface changes

API changes

Data model changes

CommentFileSizeAuthor
#91 interdiff_81-87.txt2.02 KBvacho
#87 2808063-87-conflict-tests-only.patch7.67 KBAnonymous (not verified)
#81 interdiff-61-81.txt485 bytesAnonymous (not verified)
#81 2808063-81.patch7.26 KBAnonymous (not verified)
#79 interdiff-61-79.txt478 bytesAnonymous (not verified)
#79 2808063-79.patch7.25 KBAnonymous (not verified)
#77 100_ConfigImportUITest_runs-2808063-77.patch7.28 KBAnonymous (not verified)
#61 interdiff-61_false-isset.txt729 bytesAnonymous (not verified)
#61 interdiff-43-61-assert_false.txt2.23 KBAnonymous (not verified)
#61 assert_isset-2808063-61.patch6.84 KBAnonymous (not verified)
#61 assert_false-2808063-61.patch6.85 KBAnonymous (not verified)
#54 interdiff-43-54.txt1.61 KBAnonymous (not verified)
#54 not_now_assert_2808063-54.patch7.06 KBAnonymous (not verified)
#43 interdiff-40-43.txt823 bytesAnonymous (not verified)
#43 2808063-43.patch7.35 KBAnonymous (not verified)
#40 interdiff-27-40.txt4.18 KBAnonymous (not verified)
#40 interdiff-39-40.txt3.96 KBAnonymous (not verified)
#40 2808063-40.patch7.53 KBAnonymous (not verified)
#39 interdiff-36-39.txt1.87 KBAnonymous (not verified)
#39 2808063-39.patch8.74 KBAnonymous (not verified)
#36 interdiff-33-36.txt3.09 KBAnonymous (not verified)
#36 2808063-36.patch8.36 KBAnonymous (not verified)
#33 interdiff-27-33.txt2.47 KBAnonymous (not verified)
#33 2808063-33.patch8.59 KBAnonymous (not verified)
#27 interdiff-21-27.txt1.02 KBmartin107
#27 build_by_extension_exception-2808063-27.patch7.73 KBmartin107
#21 interdiff-13-21.txt2.73 KBmartin107
#21 build_by_extension_exception-2808063-21.patch7.67 KBmartin107
#13 interdiff-2808063-9-13.txt5.03 KBmartin107
#13 build_by_extension_exception-2808063-13.patch7.45 KBmartin107
#9 build_by_extension_exception-2808063-9.patch6.02 KBchi
#5 interdiff-2808063-4-5.txt720 bytesmartin107
#5 build_by_extension_exception-2808063-5.patch3.01 KBmartin107
#4 build_by_extension_exception-2808063-4.patch2.57 KBchi

Comments

catch created an issue. See original summary.

dawehner’s picture

What would be the expected behaviour, maybe throw an exception? Is that a BC break? Is this a BC break we actually "care" about?

martin107’s picture

How about an assert instead of an exception?

that way there is no BC break for production sites

but users of dev sites get the appropriate early warning indication.

chi’s picture

Status: Active » Needs review
StatusFileSize
new2.57 KB

I would not consider this as BC break unless someone provides a good use case of using buildByExtension() against non existing extensions.

martin107’s picture

StatusFileSize
new3.01 KB
new720 bytes

This solution looks good... a minor adjustment we need a @throws

The last submitted patch, 4: build_by_extension_exception-2808063-4.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 5: build_by_extension_exception-2808063-5.patch, failed testing.

martin107’s picture

Assigned: Unassigned » martin107

I will fix the tests.

chi’s picture

Status: Needs work » Needs review
StatusFileSize
new6.02 KB

@martin107 sorry, I noticed your assignment too late. Feel free to review / fix this patch.

wim leers’s picture

Status: Needs review » Needs work
Issue tags: +DX (Developer Experience), +TX (Themer Experience)
+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
@@ -63,6 +74,8 @@ public function __construct($root, ModuleHandlerInterface $module_handler, Theme
+   * @throws \InvalidArgumentException
+   *   Thrown when the extension is not installed.

@@ -79,9 +92,12 @@ public function buildByExtension($extension) {
+        throw new \InvalidArgumentException("The following extension is not installed in your system: $extension.");

Two problems with this:

  1. The message is too generic. Something like The library '%s' could not be found because its extension '%s' is not installed. would be better, because it'd be in line with the other exceptions.
  2. This should not use InvalidArguemntException, but should add a new exception class: we already have 5 such specific exception classes, this should have one too. Perhaps a LibraryNotFoundException (this is very similar to a 404 page not found after all).

Other than that, this looks splendid! Once that's fixed, this is RTBC.

chi’s picture

The library '%s' could not be found.

This method builds information for all libraries in an extension, not just for particular library.

LibraryNotFoundException

This is not quite accurate because we are not looking for a library but for extension. I propose something like this: ExtensionNotFoundException or ExtensionMissingException.

wim leers’s picture

Sounds good!

martin107’s picture

Assigned: martin107 » Unassigned
Status: Needs work » Needs review
StatusFileSize
new7.45 KB
new5.03 KB

@Chi regarding #9 -- Ah no problem - a happy accident. My solution was similar to yours - and it is always good to see another person's thinking.

Your solution to the AjaxTest showed me that my solution would not work!

Regarding LibraryDiscoveryParserTest::setup()

If I may criticise constructively setting a mock that always returns TRUE is a little too permissive.

My preference is to only return true when required - That has the benefit that when other test code accidentally get past the moduleHandler->moduleExists() method call then an extra error will be triggered.

I have also added LibraryDiscoveryParserTest::testUnistalledTheme() which covers our new exception explicitly.

Regarding the name of the exception

NotFound has different meaning in terms of http requests and "is the file found on disc".
Missing has similar issue for me.

So I look at the documentation surrounding themeExists and moduleExits and saw that exists is used as another word for installed.

PS
Also I am going to file a separate issue - the documented list of @throw statements is not upto date.

martin107’s picture

chi’s picture

Status: Needs review » Needs work
  1. +++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
    @@ -161,6 +175,21 @@ public function testInvalidLibrariesFile() {
    +   * @expectedException \InvalidArgumentException
    

    Shall we change this to ExtensionDoesNotExistException?

  2. +++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
    @@ -161,6 +175,21 @@ public function testInvalidLibrariesFile() {
    +  public function testUnistalledTheme() {
    

    The name can be more meaningful. We are not testing uninstalled theme and did not ever uninstall themes in this case. We just make sure that the exception is thrown if non existing extension was passed to buildByExtension() method. I propose testMissingExtension or test testNotExistingExtension and so on.

The last submitted patch, 13: build_by_extension_exception-2808063-13.patch, failed testing.

chi’s picture

+++ b/core/tests/Drupal/FunctionalJavascriptTests/Ajax/AjaxTest.php
@@ -53,7 +53,7 @@ public function testDrupalSettingsCachingRegression() {
-    $fake_library = 'fakeLibrary/fakeLibrary';

So in case of Bartik it would read as follows:

Theme extension 'Bartik' could not be found because its extension 'Bartik' is not installed

Sounds a bit weird to me. Also note that this exception will be thrown for missing modules as well. Actually if the extension is missing we have no idea what type it is supposed to be. I suggest we return previous wording discussed above.

wim leers’s picture

Thanks! Great teamwork here :)

  1. +++ b/core/lib/Drupal/Core/Asset/Exception/ExtensionDoesNotExistEception.php
    @@ -0,0 +1,10 @@
    + * Defines a custom exception if a theme is not installed.
    

    s/a theme/an extension/

  2. +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
    @@ -74,8 +75,8 @@ public function __construct($root, ModuleHandlerInterface $module_handler, Theme
    +   *   Thrown when the theme or module is not installed.
    

    s/theme or module/library's extension/

  3. +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
    @@ -96,7 +97,7 @@ public function buildByExtension($extension) {
    +        throw new ExtensionDoesNotExistException(sprintf("Theme extension '%s' could not be found because its extension '%s' is not installed",  $extension));
    

    You're passing only one argument: $extension, but there are two '%s' occurrences.

    Plus the message does not make a ton of sense. What about The extension '%s' is not installed.

  4. +++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
    @@ -172,6 +175,21 @@ public function testInvalidLibrariesFile() {
    +   * @expectedException \InvalidArgumentException
    

    This was not yet updated, and hence the test should fail.

  5. +++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
    @@ -172,6 +175,21 @@ public function testInvalidLibrariesFile() {
    +  public function testUnistalledTheme() {
    

    s/Uinstalled/Uninstalled/


PS
Also I am going to file a separate issue - the documented list of @throw statements is not upto date.

+1, thank you!

dawehner’s picture

What about The extension '%s' is not installed.

What about is not installed OR is not available

martin107’s picture

Assigned: Unassigned » martin107

Most of the things to fix are the results of myself being in a rush ... so it is down to me to fix.. I will sort this out tonight ( in about 4 hours )

martin107’s picture

Assigned: martin107 » Unassigned
Status: Needs work » Needs review
StatusFileSize
new7.67 KB
new2.73 KB

#19

If I do for example drush en flag, without first downloading the contrib module. Then it is auto downloaded for me.
So when you say

What about is not installed OR is not available

"available" implies to me that it could be if some kind of helpful fallback mechanism were invoked. That is not what is suggested by the wording of the documentation above ThemeHandlerInterface::moduleExists() - or as far a I can see what happens in the underlying implementation. So for the moment I went with

The extension '%s' is not installed.

Thank you all for the corrections - I think I got to all of them

For our new tests I went with "testMissingExtension".

martin107’s picture

I just noticed a little flaw, which is out of scope for this issue.

wim leers’s picture

Status: Needs review » Needs work
+++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
@@ -161,6 +175,28 @@ public function testInvalidLibrariesFile() {
+   * @expectedException \Drupal\Core\Asset\Exception\ExtensionDoesNotExistException

Let's also assert the expected message.

Also, we don't use @expectedException anymore, PHPUnit is deprecating that.

Use setExpectedException() instead.

After that, this is RTBC IMHO.

martin107’s picture

If it is ok with you I would like to fix that up in a follow up

so that we can refactor all the other @expectedException()'s in the asset library system.

wim leers’s picture

Status: Needs review » Needs work

Well, you still need to add assert the message. NW for that.

I'm fine with doing the conversion in a follow-up, but I know that committers have demanded that we add no new code that uses the deprecated mechanism.

martin107’s picture

Assigned: Unassigned » martin107

no new code that uses the deprecated mechanism

I am happy to be held to that line.... I will patch that here.

martin107’s picture

Assigned: martin107 » Unassigned
Status: Needs work » Needs review
StatusFileSize
new7.73 KB
new1.02 KB
wim leers’s picture

Status: Needs review » Reviewed & tested by the community

Perfect :)

catch’s picture

Title: LibraryDiscoveryParser::buildByExtension() doesn't validate that themes exist » LibraryDiscoveryParser::buildByExtension() doesn't validate that extensions exist
catch’s picture

Status: Reviewed & tested by the community » Needs review

Not sure about changing the php warning to exception here.
This isn't really an issue with a 'bc break', but it's more about if you've already got a site with a buggy module on it, let's not make it even worse for you when you update.

We could continue to do a warning with E_USER_WARNING, but without trying to include the file. That way if someone somehow is running on production with this error they won't get a worse error than now. Or the assert that dawehner suggested could be good too. Possibly both so it's an early fail on dev but still logs on production?

chi’s picture

@catch this sounds like a new Core development policy that needs to be discussed and adopted globally.
Stop creating new exceptions until Drupal 9 to keep BC.

For me this case is not BC breaking. Building library information for non-existing extension is certainly a bug. It's not like PHP notices which can just spam watchdog but still let site work.

Anonymous’s picture

@Chi, you are very harsh!) Ordinary users have enough pain from other problems of D8. Do you really want to give them a white screen for the fact that they are updated? When Drupal updated form 8.1.3 to 8.1.4, rose panic. Now it will be the same. Although your arguments and look logical, but please be tolerant)

Anonymous’s picture

StatusFileSize
new8.59 KB
new2.47 KB

I wanted implement both variants (Exception for 'dev', and Log for 'prod'), but I don't know how to get environment value. Only found it as protected property of DrupalKernel class. Any hints?

catch’s picture

@vaplas there's no prod/dev switch in core, but you can use assertions which achieve much the same thing, see https://www.drupal.org/node/2492225

Status: Needs review » Needs work

The last submitted patch, 33: 2808063-33.patch, failed testing.

Anonymous’s picture

StatusFileSize
new8.36 KB
new3.09 KB

@catch, many thanks!

Anonymous’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 36: 2808063-36.patch, failed testing.

Anonymous’s picture

Status: Needs work » Needs review
StatusFileSize
new8.74 KB
new1.87 KB
Anonymous’s picture

StatusFileSize
new7.53 KB
new3.96 KB
new4.18 KB
wim leers’s picture

Status: Needs review » Needs work
  1. +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
    @@ -79,9 +92,21 @@ public function buildByExtension($extension) {
    +        \Drupal\Component\Assertion\Handle::register();
    

    This line is not necessary.

  2. +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
    @@ -79,9 +92,21 @@ public function buildByExtension($extension) {
    +        if(function_exists('drupal_set_message')) {
    +          drupal_set_message($message, 'error');
    +        }
    

    This must be removed.

  3. +++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
    @@ -79,9 +92,21 @@ public function buildByExtension($extension) {
    +        return NULL;
    

    This can just be return;.

wim leers’s picture

@catch: Sorry for not thinking of that!

Anonymous’s picture

Status: Needs work » Needs review
StatusFileSize
new7.35 KB
new823 bytes
wim leers’s picture

Status: Needs review » Reviewed & tested by the community
catch’s picture

+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
@@ -79,9 +92,15 @@ public function buildByExtension($extension) {
+        assert(false, $message);

This isn't really the right way to use asserts - normally you'd assert the actual thing you're testing against. However I'm not sure doing it differently would be any neater here.

wim leers’s picture

#45: I went through the exact same train of thought when reviewing this.

catch’s picture

+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
@@ -79,9 +92,15 @@ public function buildByExtension($extension) {
+      elseif ($this->themeHandler->themeExists($extension)) {
         $extension_type = 'theme';
       }
+      else {
+        $message = sprintf('The extension "%s" is not available.', $extension);
+        assert(false, $message);
+        trigger_error($message, E_USER_WARNING);
+        return;
+      }

What about:


elseif ($theme_exists = $this->themeHandler->themeExists($extension)) {
}
else {
  assert($theme_exists, $message)
}

Then it's clear why it's failing maybe? Or if not we should add a comment.

alexpott’s picture

Wouldn't an assert normally be: assert('$this->themeHandler->themeExists($extension)', $message);

But also I don't really get why we're doing both an assert and a trigger_error(). If we're going to trigger an error that should suffice, no?

alexpott’s picture

Status: Reviewed & tested by the community » Needs review

I think this issue should be 'needs review' till the assert thing is decided on.

Anonymous’s picture

if ($extension === 'core') {
  $extension_type = 'core';
}
elseif ($this->moduleHandler->moduleExists($extension)) {
  $extension_type = 'module';
}
elseif ($this->themeHandler->themeExists($extension)) {
  $extension_type = 'theme';
}
else{
  $message = sprintf('The extension "%s" is not available.', $extension);
  assert($extension_type, $message);
  trigger_error($message, E_USER_WARNING);
  return;
}

if($extension_type === 'core') {
  $path = 'core';
}
else {
  $path = $this->drupalGetPath($extension_type, $extension);
}
catch’s picture

An assert would be a hard-fail on dev, that's the only reason to do it - so maybe we should just skip it and leave the rest the same?

wim leers’s picture

Well, a hard fail is what you want while developing. It's just that we can't have a hard fail for existing production sites that happen to run with assertions turned on. But that means we can't have this assert at all, period. Which means we must only have the trigger_error(…, E_USER_WARNING)?

catch’s picture

It's just that we can't have a hard fail for existing production sites that happen to run with assertions turned on.

I don't think we need to support assertions being enabled on production. The question for me is more - do we support not having assertions on for development. If we removed the trigger_error() and left the assert, the effect would be a silent fail on prod and a hard fail on dev if assertions are on, but otherwise silent again.

Anonymous’s picture

StatusFileSize
new7.06 KB
new1.61 KB

Anyway, we can make only first step and fix "Provide a more useful error message". And then, if necessary, open new issue to improve it via assert or exception.

wim leers’s picture

do we support not having assertions on for development

I think we don't need to support that. It's already a best practice to use settings.local.php for development, and that enables assertions by default.

I'm not a fan of logging this as a warning, because that is far too easy to miss. I wouldn't think to go and check the error log after modifying my *.libraries.yml file…

dawehner’s picture

Status: Needs review » Needs work

I agree with @Wim Leers, let's go with just assertions. We should not treat libraries in some special way.

catch’s picture

Yeah I think that's fair enough overall, sorry for confusing things a bit.

wim leers’s picture

Issue tags: +Needs reroll

So we want #43, but with the trigger_error() removed.

Anonymous’s picture

Guys, I think you are the best, but now I confused definitely)

Example. If I have code:

$variables['#attached']['library'][] = 'missing/extension';

then when using trigger_error I get:

Warning: Invalid argument supplied for foreach() in Drupal\Core\Asset\LibraryDiscovery->getLibrariesByExtension()
User warning: The extension "missing" is not available.
...

Ok, user warning appears only once (and without '/extension' part), but it's better than never.

Without trigger_error i have only 'Warning: Invalid argument..' and i don't undestand what it message means.

a best practice to use settings.local.php for development, and that enables assertions by default

but zend.assertions = -1 by default. Maybe we need to add info to "Status report" with the recommendation to change php.ini settings, if using settings.local.php?

I'm not a fan of logging this as a warning, because that is far too easy to miss.

If we have a better alarm about new entries in the journal, I would have seen them.

We should not treat libraries in some special way.

Hence Exception instead Assert?

So we want #43, but with the trigger_error() removed.

What better using:

assert(false, $message); like #43
assert(FALSE, $message); like line 29 in core/lib/Drupal/Core/DependencyInjection/Container.php
assert($theme_exists, $message); like #47
assert($extension_exists, $message); like #47, but with general name
assert('$this->themeHandler->themeExists($extension)', $message); like #48
assert(isset($extension_type), $message); like #50 (typo: add isset, because undefined variable error)

wim leers’s picture

Yes, sorry for all the confusion!


but zend.assertions = -1 by default. Maybe we need to add info to "Status report" with the recommendation to change php.ini settings, if using settings.local.php?

When using settings.local.php, assertions are enabled automatically through this:

assert_options(ASSERT_ACTIVE, TRUE);

The default value in php.ini is irrelevant.


So let's go with either:

  …
  $extension_type = 'theme'
}
else {
  assert(FALSE, sprintf('The extension "%s" is not available.', $extension));
}

or:

  …
  $extension_type = 'theme'
}
assert(isset($extension_type), sprintf('The extension "%s" is not available.', $extension));
Anonymous’s picture

@Wim Leers, thank you very much!
I forgot to say that checking on php7. With php 7 assert_options(ASSERT_ACTIVE, TRUE); not work if zend.assertions = -1 documentation (but documentation says that by default 1, although in reality -1)

Anonymous’s picture

Status: Needs work » Needs review
wim leers’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs reroll

#61: if that PHP7 behavior were true, then any Drupal 8 unit test involving assertions would fail. Since they don't, it must be working.

I like that @catch can now choose between either approach :)

The last submitted patch, 61: assert_false-2808063-61.patch, failed testing.

The last submitted patch, 61: assert_false-2808063-61.patch, failed testing.

The last submitted patch, 61: assert_false-2808063-61.patch, failed testing.

  • catch committed a68c44f on 8.3.x
    Issue #2808063 by vaplas, martin107, Chi, Wim Leers, catch, dawehner,...
catch’s picture

Version: 8.2.x-dev » 8.3.x-dev
Status: Reviewed & tested by the community » Fixed

Let's go for isset(), seems more self-documenting. Committed/pushed to 8.3.x, thanks! Don't think it needs to be in 8.2.x

  • catch committed d46fefc on 8.3.x
    Revert "Issue #2808063 by vaplas, martin107, Chi, Wim Leers, catch,...
catch’s picture

Status: Fixed » Needs review

Annnd that fails on PHP 7 with the assertion message.

wim leers’s picture

Eh… why?

  • catch committed a68c44f on 8.4.x
    Issue #2808063 by vaplas, martin107, Chi, Wim Leers, catch, dawehner,...
  • catch committed d46fefc on 8.4.x
    Revert "Issue #2808063 by vaplas, martin107, Chi, Wim Leers, catch,...

  • catch committed a68c44f on 8.4.x
    Issue #2808063 by vaplas, martin107, Chi, Wim Leers, catch, dawehner,...
  • catch committed d46fefc on 8.4.x
    Revert "Issue #2808063 by vaplas, martin107, Chi, Wim Leers, catch,...

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

wim leers’s picture

Status: Needs review » Reviewed & tested by the community

I'd bet this was a PHP 7 bug that has been fixed since. Retesting and re-RTBC'ing.

It's a shame we lost track of this for the past six months… :/

Anonymous’s picture

Status: Reviewed & tested by the community » Needs review

Exactly! But .. it's devilishly frequent randomly fails with ConfigImportInstallProfileTest and ConfigImportUITest.

Maybe this is the same boss of random fails (Config schema generation), which @alexpott mentioned in #2828559-127: UpdatePathTestBase tests randomly failing?

Rerolled #61 with 100 runs of ConfigImportUITest (also bit research here #17 - #22).

Anonymous’s picture

Status: Needs review » Needs work

The last submitted patch, 77: 100_ConfigImportUITest_runs-2808063-77.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Anonymous’s picture

Status: Needs work » Needs review
StatusFileSize
new7.25 KB
new478 bytes

Looks like in case of a fall the themeHandler->themeExists() uses an outdated list of themes. After the list is reset, the tests begin to work more stable. (see 28-29 posts in #2879048: Ignore: patch testing issue for #2919863).

Status: Needs review » Needs work

The last submitted patch, 79: 2808063-79.patch, failed testing. View results

Anonymous’s picture

Status: Needs work » Needs review
StatusFileSize
new7.26 KB
new485 bytes

Opps, it was a bit ambitious to forget about the other tests, sorry.

dawehner’s picture

+++ b/core/lib/Drupal/Core/Extension/ThemeHandler.php
@@ -474,6 +474,7 @@ public function getThemeDirectories() {
   public function themeExists($theme) {
+    $this->rebuildThemeData();

It feels like rebuilding this information all the time is not the best approach. Is there no other way to fix it?

Anonymous’s picture

Status: Needs review » Needs work

@dawehner, thanks for review. Yeah, rebuildThemeData() is absolutely not the best approach, and it not help to stable tests for ConfigImportInstallProfileTest and ConfigImportUITest.

$this->list = NULL; helps to stabilize these tests, but causes 216 fails in other tests :) And it also not good approach :(

I'm just trying to get close to the root of the problem. But for me it's not easy, especially because I can not reproduce the problem locally.

My main assumption is that Mr. Bot works so fast (especially with php7) that the cached value of list does not have time to update.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

catch’s picture

Priority: Normal » Major

Bumping this to major, if you set the admin theme to 'default', it is saved as '0' in configuration, and code is trying to load that theme with drupal_get_filename(), so you get:

 User warning: The following theme is missing from the file system: 0 in drupal_get_filename() (line 268   
                                                  of web/core/includes/bootstrap.inc)
Anonymous’s picture

Added related issues to #86 point.

Reuploaded #61 with conflict tests only.

Some observations (from experiments in the ignore-issue (#2948180-45 and more), because i still cann't reproduce fails locally):

1. PHP 5.5 + Postgresql 9.1 works more stable than PHP 7.2 + MySQL 5.5 (Is the quick execution of the code causing a problem?)

2. Tests work stable if we adding to LibraryDiscoveryParser:

 elseif ($this->themeHandler->themeExists($extension)) {
   $extension_type = 'theme';
 }
+ else {
+   $extension_type = 'theme';
+ }

So that issue only highlights the problem, and does not create it.

3. refresh theme list before checking $extension is sufficient for ConfigImportUITest, but not for ConfigImportInstallProfileTest.

4. ConfigImportInstallProfileTest does not contain \Drupal::cache('bootstrap')->get('system_list'). And 'classy' has status 0 in \Drupal::state()->get('system.theme.data') on DI (but locally everything is ok).

5. Locally ConfigImportInstallProfileTest adds info about 'classy' inside of the batch procces (during parsing dependencies to 'core/html5shiv' library). On DI this does not happen, and search for dependencies in the batch process is not performed at all.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

almaudoh’s picture

Found this issue trying to fix a test fail from #2347783: Deprecate drupal_get_path() and drupal_get_filename() and replace with ExtensionList::getPath() and ExtensionList::getPathname(). I don't know if we still need this issue after #2347783 is done since ExtensionLists throw the UnknownExceptionExtension if they are called on a non-existent extension. Some parts of the patch here may still be useful.

andypost’s picture

Issue tags: +Needs reroll, +Needs rework
vacho’s picture

StatusFileSize
new2.02 KB

Adding diff between 81 and 87 patches.

vacho’s picture

Issue tags: -Needs reroll

This patch no need reroll.

rodrigoaguilera’s picture

We should look closely at
#2347783: Deprecate drupal_get_path() and drupal_get_filename() and replace with ExtensionList::getPath() and ExtensionList::getPathname()

Becuse it might be introducing more bugs about by not failing when you try to get the path but trying to invoke alter hooks on modules that are not enabled.

I will try to introduce a test in that other issue for this.

rodrigoaguilera’s picture

Title: LibraryDiscoveryParser::buildByExtension() doesn't validate that extensions exist » [PP-1] LibraryDiscoveryParser::buildByExtension() doesn't validate that extensions exist
Status: Needs work » Postponed

I can confirm that
#2347783: Deprecate drupal_get_path() and drupal_get_filename() and replace with ExtensionList::getPath() and ExtensionList::getPathname()
Will solve this issue by throwing an Drupal/Core/Extension/Exception/UnknownExtensionException

What still bothers me is that I confirmed that
LibraryDiscoveryParser::buildByExtension()

will return information from themes that exist in the filesystem but are not active but for modules it will only return information for those that are enabled. When you query for a module that is in the filesystem but not enabled it will assume is a theme giving a confusing exception message like:

Drupal/Core/Extension/Exception/UnknownExtensionException with message 'The theme non_enabled_module does not exist.'

Should we repurpose this issue to fix that or open a new one?

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

joachim’s picture

Title: [PP-1] LibraryDiscoveryParser::buildByExtension() doesn't validate that extensions exist » LibraryDiscoveryParser::buildByExtension() doesn't validate that extensions exist
Status: Postponed » Needs work

I don't think this issue need to be postponed. Whichever of this and #2347783: Deprecate drupal_get_path() and drupal_get_filename() and replace with ExtensionList::getPath() and ExtensionList::getPathname() gets in first will cause a reroll of the other one, but the other issue doesn't fix this faulty logic:

      if ($this->moduleHandler->moduleExists($extension)) {
        $extension_type = 'module';
      }
// WRONG! Just because the module doesn't exist, doesn't mean it must be a theme!
      else {
        $extension_type = 'theme';
      }

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

larowlan’s picture

+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
@@ -79,9 +92,10 @@ public function buildByExtension($extension) {
+      elseif ($this->themeHandler->themeExists($extension)) {
         $extension_type = 'theme';
       }
+      assert(isset($extension_type), sprintf('The extension "%s" is not available.', $extension));

we're also forgetting the profile extension type here

larowlan’s picture

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

catch’s picture

Priority: Major » Normal

This is still valid but downgrading to normal.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.