Problem/Motivation
When using this module we are getting a TypeError after the plugin redirects.
TypeError: Drupal\facets\FacetManager\DefaultFacetManager::sortFacetResults(): Argument #2 ($results) must be of type array, null given, called in /app/web/modules/contrib/facets/src/FacetManager/DefaultFacetManager.php on line 350 in Drupal\facets\FacetManager\DefaultFacetManager->sortFacetResults() (line 510 of /app/web/modules/contrib/facets/src/FacetManager/DefaultFacetManager.php)
ActiveByDefaultProcessor breaks the BuildProcessorInterface as it does not return a value and execution continues. This results in $results becoming NULL as the DefaultFacetManager builds the facet.
Steps to reproduce
- Enable the module and configure a facet to redirect to the first item
- Ensure the facet has at least 1 sort plugin configured
- Navigate to the search result
- Observe you have been redirect
- Observe the error is in the logs
Proposed resolution
Drupal discourages terminating the execution mid-request. We should return the results as is defined by the interface.
While investigating this I found that the redirect is not performed exactly as documented in https://www.drupal.org/node/2023537
- Ensure the session is saved and kernel events are triggered as per "Redirecting when not in context of a controller" under https://www.drupal.org/node/2023537
- return results
Remaining tasks
Patch- Review
- Commit
User interface changes
n/a
API changes
n/a
Data model changes
n/a
| Comment | File | Size | Author |
|---|---|---|---|
| #5 | facet_active_by_default-terminate-execution-after-redirect-3366611-3.patch | 3.3 KB | ericgsmith |
| #3 | interdiff_2_3.txt | 442 bytes | ericgsmith |
Comments
Comment #2
ericgsmith commentedComment #3
ericgsmith commented*EDIT* Apoliges this is the wrong patch attached here
After conversation with a colleague I've removed an earlier implementation containing exit in favour of returning the results.
Comment #4
ericgsmith commentedComment #5
ericgsmith commentedSorry - wrong patch attached earlier
Comment #6
xurizaemonThanks Eric. It feels like sending a RedirectResponse really ought to trigger termination of the current request, to me.
(EDIT: By which I mean ... I think the proposed change looks correct, but I feel like it should be unnecessary to introduce and then terminate the kernel request as I feel like that would be sensible default behaviour for core when sending a RedirectResponse already.)
I don't see that, but wanted to check in case we'd missed something there.
Comment #7
ericgsmith commentedHi Chris,
Sorry I missed this message when I was on leave.
You are correct - if core was doing the send we wouldn't need to do this - the issue is that the plugin is sending the response so that plugin needs to ensure it is terminated. If this was redirecting somewhere that core expected (e.g middleware, a controller or event subscriber) it wouldn't be needed.
The main different here is that its not good to be sending your own responses - core should be doing that. But at the same time its relying on information this isn't available until the query to solr has run and the response is being built.
Another option would be to add a kernel event listener to the event dispatcher - this is what core does in the drupal goto plugin https://git.drupalcode.org/project/drupal/-/blob/11.x/core/lib/Drupal/Co...
This would let the request complete and be handle by Drupal - less code / logic for the module - but it not what the (admittedly dated) CR says about redirect outside the context of a controller - https://www.drupal.org/node/2023537
Comment #9
azinck commentedThanks for the fix!