Problem/Motivation

After #3495318: Remove the ability for the project_browser.browse route to take a project ID
The browse method could receive an empty or null value with "/admin/modules/browse"

Steps to reproduce

When having a custom source provider as "/admin/modules/browse/myapps"
Or not found or disabled one like "/admin/modules/browse/no-source"
redirect to the fallback route "/admin/modules/browse" with the first default source to browse with.

Then we hit the following fatal error

AssertionError: assert($source instanceof ProjectBrowserSourceInterface) in assert() (line 117 of modules/contrib/project_browser/src/Element/ProjectBrowser.php).
Drupal\project_browser\Element\ProjectBrowser->getDrupalSettings() (Line: 96)
Drupal\project_browser\Element\ProjectBrowser->attachProjectBrowserSettings()
call_user_func_array() (Line: 107)
Drupal\Core\Render\Renderer->doTrustedCallback() (Line: 825)
Drupal\Core\Render\Renderer->doCallback() (Line: 387)
Drupal\Core\Render\Renderer->doRender() (Line: 203)
Drupal\Core\Render\Renderer->render() (Line: 238)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 593)
Drupal\Core\Render\Renderer->executeInRenderContext() (Line: 231)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare() (Line: 128)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse() (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray() (Line: 246)
Symfony\Component\EventDispatcher\EventDispatcher::Symfony\Component\EventDispatcher\{closure}() (Line: 206)
Symfony\Component\EventDispatcher\EventDispatcher->callListeners() (Line: 56)
Symfony\Component\EventDispatcher\EventDispatcher->dispatch() (Line: 188)
Symfony\Component\HttpKernel\HttpKernel->handleRaw() (Line: 76)
Symfony\Component\HttpKernel\HttpKernel->handle() (Line: 53)
Drupal\Core\StackMiddleware\Session->handle() (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle() (Line: 28)
Drupal\Core\StackMiddleware\ContentLength->handle() (Line: 32)
Drupal\big_pipe\StackMiddleware\ContentLength->handle() (Line: 116)
Drupal\page_cache\StackMiddleware\PageCache->pass() (Line: 90)
Drupal\page_cache\StackMiddleware\PageCache->handle() (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() (Line: 36)
Drupal\Core\StackMiddleware\AjaxPageState->handle() (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle() (Line: 709)
Drupal\Core\DrupalKernel->handle() (Line: 19)

Proposed resolution

  • Refactor the browse() method to improve the fallback logic for an empty $source.
  • Validate the default first enabled_sources from the project_browser.admin_settings configs
Command icon 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

rajab natshah created an issue. See original summary.

rajab natshah’s picture

Assigned: rajab natshah » Unassigned
Status: Active » Needs review
rajab natshah’s picture

Attached a static file project_browser--2025-01-13--3499406--mr-672.patch file from MR672
To be used with Composer Patches

dunx’s picture

I've just raised https://www.drupal.org/project/project_browser/issues/3499630 which is a different error message experienced on a fresh D11.1 install, which looks to be related to project_browse.browse

tim.plunkett’s picture

I think this is a duplicate of #3500024: WSOD when accessing non-enabled or non-existent source plugin
Or at least they are different approaches to the same underlying problem

phenaproxima’s picture

Status: Needs review » Closed (duplicate)
Related issues: +#3500024: WSOD when accessing non-enabled or non-existent source plugin

Closing as a duplicate of #3500024: WSOD when accessing non-enabled or non-existent source plugin, which has a more complete and robust fix. It should not be possible to access /admin/modules/browse without a source plugin ID.

rajab natshah’s picture

Thanks for following up! Moving to follow with the better logic.

rajab natshah’s picture

Project Browser 2.0.0-alpha8 was released on: 30 Jan 2025 by: chrisfromredfin


Thanks, Chris

Still running into this error even after the release of project_browser 2.0.0-alpha8, which includes #3500024: WSOD when accessing non-enabled or non-existent source plugin.

Anyone else seeing this?

Symfony\Component\Routing\Exception\MissingMandatoryParametersException: Some mandatory parameters are missing ("source") to generate a URL for route "project_browser.browse". in Drupal\Core\Routing\UrlGenerator->doGenerate() (line 187 of core/lib/Drupal/Core/Routing/UrlGenerator.php).

I am not sure what’s wrong with my setup. ( Maybe issues with old setup or old configs )
I am just using the default under Drupal 10.4.1

Is Project Browser now only for Drupal 11?

Error message
Unsupported version: Upgrade to Drupal 11 to continue using Project browser, details are in this announcement.

rajab natshah’s picture

Attached a static project_browser--2025-01-30--3499406-10.patch file as a TEMP fix.

To use with Composer Patches

Having

project_browser.browse:
  path: '/admin/modules/browse/{source}'
  defaults:
    _controller: '\Drupal\project_browser\Controller\BrowserController::browse'
    _title: 'Browse projects'
    source: Drupal\project_browser\Plugin\ProjectBrowserSourceInterface
  requirements:
    _permission: 'administer modules'
  options:
    parameters:
      source:
        project_browser.source: true

And

  public function browse(ProjectBrowserSourceInterface $source): array {

    // If $source is not set, determine a default source.
    if (!isset($source)) {
      // Retrieve the list of enabled sources from project browser admin settings.
      $enabled_sources = $this->config('project_browser.admin_settings')->get('enabled_sources') ?? [];

      // If at least one enabled source exists, use the first one as the default.
      if (!empty($enabled_sources) && isset($enabled_sources[0])) {
        $source = $enabled_sources[0];
      }
    }

    return [
      '#type' => 'project_browser',
      '#source' => $source,
    ];
  }