elasticsearch-php
elasticsearch-php copied to clipboard
TypeError in error handling code of Connection.php
I have a setup where the ES host isn't set correctly, which then leads to an error in the error handling itself. I'm using version 6.7.2, but from reading the code, the issues below are still present in the latest code.
The code that triggers this is roughly:
/** @var Client $elasticsearch */
$elasticsearch->indices()->exists(['index' => ['test']]);
When stepping through the code, this ends up in Connection::wrapHandler(), line 223 and $response['error'] is an instance of GuzzleHttp\Exception\ConnectException. I believe one bug in the code is the type check in that line, because it checks for the wrong GuzzleHttp\Ring\Exception\ConnectException. Another indicator is that the check as it stands is redundant, because ConnectException derives from RingException there. Just changing the type of this doesn't solve the issue though, it then breaks in a different place.
The second bug is the way this is processed then. At line 273 there is a call to logRequestFail() with $response['effective_url'] as second parameter. This field isn't set though, so null is passed, which is then passed to buildCurlCommand() and from there to strpos(). Note that newer code fails a bit differently, because it has type annotations on buildCurlCommand() which will prevent null from reaching strpos(), but the problem itself is still present. Replacing $response['effective_url'] ?? $request['uri'] in the call to logRequestFail() seems to do the job for me. I'm not sure this is a good fix because firstly, the null coalescing operator isn't present in all PHP versions and secondly, making the logged data depend on a response that never arrived might be the cause of all this.
System details
- Operating System: Elementary and Debian
- PHP Version 7.3.17
- ES-PHP client version 6.7.2
- Elasticsearch version: none ;-)
Okay, update, I've extracted a demo:
<?php
use Elasticsearch\ClientBuilder;
use GuzzleHttp\Client as GuzzleHttpClient;
use LukeWaite\RingPhpGuzzleHandler\GuzzleHandler;
require_once 'vendor/autoload.php';
$client = ClientBuilder::create()
->setHandler(new GuzzleHandler(new GuzzleHttpClient([])))
->setHosts(['some-host'])
->build();
$indices = $client->indices();
$indices->exists([
'index' => 'some index',
]);
In the composer.json, I have
"elasticsearch/elasticsearch": "^6.0"
"lukewaite/ringphp-guzzle-handler": "^2.1"
The latter and its handler (new GuzzleHandler(...)) play an important role in reproducing this. I think this component can be blamed to some extent because it throws the wrong exception type. However, your code seems to be prepared for handling that but fails at that.
Hello @UlrichEckhardt
did you get any news about this error ?
I tried with 7.6.1 and still get it.
I see this error with version 7.10.0 and PHP 7.4. In my case it manifests as a type error when there is a connection failure to an Elasticsearch host.
Here is the stack trace:
PHP Fatal error: Uncaught TypeError: Argument 2 passed to Elasticsearch\Connections\Connection::buildCurlCommand() must be of the type string, null given, called in /var/www/releases/a8ce1aa/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Connections/Connection.php on line 447 and defined in /var/www/releases/a8ce1aa/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Connections/Connection.php:596
Stack trace:
#0 /var/www/releases/a8ce1aa/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Connections/Connection.php(447): Elasticsearch\Connections\Connection->buildCurlCommand()
#1 /var/www/releases/a8ce1aa/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Connections/Connection.php(271): Elasticsearch\Connections\Connection->logRequestFail()
#2 /var/www/releases/a8ce1aa/vendor/react/promise/src/FulfilledPromise.php(28): Elasticsearch\Connections\Connection->Elasticsearch\Connections\{closure}()
#3 /var/www/releases/a8ce1aa/vendor/ezimuel/ringphp/src/Future/CompletedFutureValue.php(55): React\Promise\FulfilledPromis in /var/www/releases/a8ce1aa/vendor/elasticsearch/elasticsearch/src/Elasticsearch/Connections/Connection.php on line 596
Hi, this was actually caused by the custom handler. This is the quite popular handler that is often used in projects (as is or just as an inspiration) - https://github.com/lukewaite/ringphp-guzzle-handler/blob/master/src/GuzzleHandler.php#L96
You may simply replace this null to the empty string and the error will be gone.