Setup
- Solr version: 7
- Drupal Core version: 8.9.13
- Search API version: 8.x-1.19
- Search API Solr version: 4.1.11
- Acquia Search: 8.x-1.22
- Configured Solr Connector: Acquia
Issue
Short summary
When viewing the Solr server a PHP TypeError is triggered because Solarium\Core\Client\Response::getStatusCode returns NULL and the function declares it returns ints.
Disclamier
I'm not sure this is a bug related to this module, but because the error is in Solarium and Search API Solr requires this library I thought this would be a good place to fill the bug report.
It is even possible this is a bug related to our setup or a combination of Search API Solr with Acquia Solr modules.
UPDATE: As per comment #2 issues has been moved to Acquia Search.
Details
The Solr server page of a configured Solr server in Acquia infra (an Acquia Cloud Site Factory) triggers the following error:
TypeError: Return value of Solarium\Core\Client\Response::getStatusCode() must be of the type int, null returned in Solarium\Core\Client\Response->getStatusCode()
This is because getStatusCode declares that it returns an int but NULL is returned.
Given that the code is just:
public function getStatusCode(): int
{
return $this->statusCode;
}
It seems $this->statusCode is not initialized.
The only function that initializes that class property is the setHeaders method of the same class. However, this method is not called during this page request.
So, it seems the Solarium\Core\Client\Response class is not properly used because getStatusCode is being called before setHeaders is called.
Logs
The error in dblog:
TypeError: Return value of Solarium\Core\Client\Response::getStatusCode() must be of the type int, null returned in Solarium\Core\Client\Response->getStatusCode() (line 88 of /mnt/gfs/myprojectdev/livedev/vendor/solarium/solarium/src/Core/Client/Response.php)
#0 /mnt/gfs/myprojectdev/livedev/docroot/modules/contrib/acquia_search/src/EventSubscriber/SearchSubscriber.php(141): Solarium\Core\Client\Response->getStatusCode()
#1 [internal function]: Drupal\acquia_search\EventSubscriber\SearchSubscriber->postExecuteRequest(Object(Drupal\search_api_solr\Solarium\EventDispatcher\EventProxy), 'Solarium\\Core\\E...', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#2 /mnt/gfs/myprojectdev/livedev/docroot/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): call_user_func(Array, Object(Drupal\search_api_solr\Solarium\EventDispatcher\EventProxy), 'Solarium\\Core\\E...', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#3 /mnt/gfs/myprojectdev/livedev/docroot/modules/contrib/search_api_solr/src/Solarium/EventDispatcher/Psr14Bridge.php(25): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('Solarium\\Core\\E...', Object(Drupal\search_api_solr\Solarium\EventDispatcher\EventProxy))
#4 /mnt/gfs/myprojectdev/livedev/vendor/solarium/solarium/src/Core/Client/Client.php(824): Drupal\search_api_solr\Solarium\EventDispatcher\Psr14Bridge->dispatch(Object(Solarium\Core\Event\PostExecuteRequest))
#5 /mnt/gfs/myprojectdev/livedev/vendor/solarium/solarium/src/Core/Client/Client.php(791): Solarium\Core\Client\Client->executeRequest(Object(Solarium\Core\Client\Request), Object(Solarium\Core\Client\Endpoint))
#6 /mnt/gfs/myprojectdev/livedev/docroot/modules/contrib/search_api_solr/src/SolrConnector/SolrConnectorPluginBase.php(609): Solarium\Core\Client\Client->execute(Object(Solarium\QueryType\Ping\Query), NULL)
#7 /mnt/gfs/myprojectdev/livedev/docroot/modules/contrib/search_api_solr/src/SolrConnector/SolrConnectorPluginBase.php(588): Drupal\search_api_solr\SolrConnector\SolrConnectorPluginBase->pingEndpoint(NULL, Array)
#8 /mnt/gfs/myprojectdev/livedev/docroot/modules/contrib/search_api_solr/src/Plugin/search_api/backend/SearchApiSolrBackend.php(723): Drupal\search_api_solr\SolrConnector\SolrConnectorPluginBase->pingCore()
#9 /mnt/gfs/myprojectdev/livedev/docroot/modules/contrib/search_api/src/Entity/Server.php(191): Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend->viewSettings()
#10 /mnt/gfs/myprojectdev/livedev/docroot/modules/contrib/search_api/search_api.theme.inc(241): Drupal\search_api\Entity\Server->viewSettings()
#11 /mnt/gfs/myprojectdev/livedev/docroot/core/lib/Drupal/Core/Theme/ThemeManager.php(332): template_preprocess_search_api_server(Array, 'search_api_serv...', Array)
#12 /mnt/gfs/myprojectdev/livedev/docroot/core/lib/Drupal/Core/Render/Renderer.php(431): Drupal\Core\Theme\ThemeManager->render('search_api_serv...', Array)
#13 /mnt/gfs/myprojectdev/livedev/docroot/core/lib/Drupal/Core/Render/Renderer.php(444): Drupal\Core\Render\Renderer->doRender(Array)
#14 /mnt/gfs/myprojectdev/livedev/docroot/core/lib/Drupal/Core/Render/Renderer.php(200): Drupal\Core\Render\Renderer->doRender(Array, false)
#15 /mnt/gfs/myprojectdev/livedev/docroot/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(226): Drupal\Core\Render\Renderer->render(Array, false)
#16 /mnt/gfs/myprojectdev/livedev/docroot/core/lib/Drupal/Core/Render/Renderer.php(573): Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}()
#17 /mnt/gfs/myprojectdev/livedev/docroot/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(227): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#18 /mnt/gfs/myprojectdev/livedev/docroot/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(117): Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch))
#19 /mnt/gfs/myprojectdev/livedev/docroot/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php(90): Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch))
#20 [internal function]: Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#21 /mnt/gfs/myprojectdev/livedev/docroot/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#22 /mnt/gfs/myprojectdev/livedev/vendor/symfony/http-kernel/HttpKernel.php(156): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.view', Object(Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent))
#23 /mnt/gfs/myprojectdev/livedev/vendor/symfony/http-kernel/HttpKernel.php(68): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#24 /mnt/gfs/myprojectdev/livedev/docroot/modules/contrib/simple_oauth/src/HttpMiddleware/BasicAuthSwap.php(67): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#25 /mnt/gfs/myprojectdev/livedev/docroot/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Drupal\simple_oauth\HttpMiddleware\BasicAuthSwap->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#26 /mnt/gfs/myprojectdev/livedev/docroot/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#27 /mnt/gfs/myprojectdev/livedev/docroot/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#28 /mnt/gfs/myprojectdev/livedev/docroot/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#29 /mnt/gfs/myprojectdev/livedev/vendor/asm89/stack-cors/src/Asm89/Stack/Cors.php(49): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#30 /mnt/gfs/myprojectdev/livedev/docroot/core/modules/ban/src/BanMiddleware.php(50): Asm89\Stack\Cors->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#31 /mnt/gfs/myprojectdev/livedev/docroot/modules/contrib/shield/src/ShieldMiddleware.php(127): Drupal\ban\BanMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#32 /mnt/gfs/myprojectdev/livedev/docroot/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\shield\ShieldMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#33 /mnt/gfs/myprojectdev/livedev/docroot/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#34 /mnt/gfs/myprojectdev/livedev/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#35 /mnt/gfs/myprojectdev/livedev/docroot/core/lib/Drupal/Core/DrupalKernel.php(708): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#36 /mnt/gfs/myprojectdev/livedev/docroot/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#37 {main}
| Comment | File | Size | Author |
|---|---|---|---|
| #8 | 3209704-8.patch | 1.56 KB | japerry |
Comments
Comment #2
mkalkbrennerIt isn't a Solarium issue. This behavior is "expected".
From the stack trace it looks like an issue in
acquia_search/src/EventSubscriber/SearchSubscriber.php. Maybe caused by another connection issue that is not obvious.Comment #3
tunicComment #4
tunicThanks mkalkbrenner!
I've updated the description.
Comment #5
tunicComment #6
janusman commentedWe've found that using the remote_stream_wrapper module with Acquia Search can trigger this problem.
If you have that module enabled... can you try disabling it?
On the other hand, the status code and other things break in a way that should also break Solarium (and in turn Search API Solr) if it's using the Solrarium HTTP (not Guzzle) adapter. The reason is that the Solarium HTTP adapter depends on https://www.php.net/manual/en/reserved.variables.httpresponseheader.php (and maybe other) PHP "quirky" variables that are created on the fly when using the HTTP stream wrapper. (I.e. file_get_contents("http://my.solr/something/or/other"))
See https://www.drupal.org/project/remote_stream_wrapper/issues/1416564 for some info.
So I think this might not JUST affect acquia_search, but also "plain" Search API Solr (since it depend on Solarium, which has this incompatibility with the remote_stream_wrappers module.
Comment #7
japerrySo while this might be an issue with how we handle requests coming back, I think the response class in solarium might be handling its null values correctly?
For instance:
If the headers are null, it doesn't set the object to empty array [], it actually keeps it as null. So if I want to see if there are headers, I think it will just return a similar error, saying 'null returned instead of array'.
But since there is a response object (because its throwing an error from the response object, instead of saying $response is null, its not possible to see if there is an error.
So I'm pretty sure this is a solarium issue.
Comment #8
japerrySo old PHP me thinks its Solarium, but in the new PHP world, maybe we should be handling these returns better?
Attached is a patch that just skips the event if a non-valid Solarium response was returned.
Comment #9
japerryThis won't work. Its a problem in remote_stream_wrapper. Tempted to mark won't fix, but looking into how we can fix it there first, and if there is no workable solution, find a workaround here.
Comment #10
japerryWe've pushed an update to Acquia Search that uses the PSR18 wrapper instead of raw HTTP. This is compatible with remote_stream_wrappers.
Comment #12
mkalkbrennerGood choice!
Comment #13
tunicI confirm this patch solved my issue.
Not only that, we had an issue connecting our site to Acquia's Solr server in their Acquia Cloud infrastructure. The problem was due to Acquia Search and Remote Stream Wrappers used in the same project. On the Drupal status page, there was this message: "Solr core authentication check fails".
With this patch, the error is gone and we are able to connect to Acquia's Solr.