Closed (fixed)
Project:
Elasticsearch Connector
Version:
8.0.x-dev
Component:
Code
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
23 Apr 2026 at 13:33 UTC
Updated:
12 May 2026 at 16:45 UTC
Jump to comment: Most recent
Comments
Comment #2
mparker17For reference, here is the list of errors (output from
ddev phpstan --level=4 --error-format=rawbut slightly formatted)...Comment #4
mparker17Turns out the fixes I made in the branch also fixed the lints for level 5, so we can go to level 5 in this issue.
Comment #5
mparker17There were a few non-comment changes to production code in this patch worth noting. I'm going to discuss them (and provide some reasoning) in the next few comments (i.e.: to make it easy for the community to discuss if necessary).
Comment #6
mparker17$this->client->indices()->exists($params)returns either a\Http\Promise\Promiseobject (if async is set in the Elasticsearch client, which we don't do), or an\Elastic\Elasticsearch\Response\Elasticsearchobject.The problem here is that objects are truthy, so this would never log the warning, even if the index did not exist. Instead, code later in the same function would try to send a query, and fail with a ElasticSearchException, which get re-thrown as a SearchApiException.
The outcome of an "index exists" call (i.e.: either TRUE => "index exists" or FALSE => "index does not exist") is captured inside the response wrapped by the
\Elastic\Elasticsearch\Response\Elasticsearchobject.Testing locally, I could see that calling
\Elastic\Elasticsearch\Response\Elasticsearch::asBool()would return TRUE when the index exists, and FALSE when the index does not exist, which seems to be what we're actually trying to check here, so I changed this to simply call ->asBoo() on the old code.The outcome of this was a test failure in \Drupal\Tests\elasticsearch_connector\Kernel\ElasticSearchBackendTest::checkModuleUninstall(), which deleted the index and expected the re-thrown SearchApiException mentioned earlier. ElasticSearchBackendTest::checkModuleUninstall overrides
\Drupal\Tests\search_api\Kernel\BackendTestBase::checkModuleUninstall()which is empty (i.e.: a no-op). Anyway, now searching on a deleted index results in a log message and not a SearchApiException, I needed to make the following change to the test...Comment #7
mparker17This code is a bit convoluted; my guess is that it evolved a bit and we left some defensive checks even though they're no longer necessary.
In the following change...
... this was the first time that
$body['query']would be set in this branch of the if/elseif, so the inner "if" statement wasn't necessary because it would always evalute to run the inner code.Likewise, in the following change...
... there was no way that
body['fields']could exist yet in this branch of the if/elseif, so the inner "if" statement wasn't necessary because it would always evaluate to skip the inner code.Comment #8
mparker17In this case,
empty($body['post_filter'])won't throw aWarning: Undefined array key 'post_filter'if thepost_filterkey doesn't exist, and instead it returns the exact same thing asisset($body['post_filter']).But if
$body['post_filter']does exist we still need to check whether its empty.This meant that the call to
\isset()was unnecessary.Comment #9
mparker17In both of these cases, calling
$this->getConnector()would throw an exception if there was a problem, and (uncaught) exceptions pop stack, so...So for this change...
... it seemed like the desired error-behavior was to set an error on the form; so I moved the call that had the potential to fail and all the code that assumes it passes into the "try" and moved the contents of the "if" statement (i.e.: behavior on failure) into the "catch" statement.
For this change...
... it seemed like the desired error-behavior was to do nothing (because there was no "else" or anything afterwards before the end of the function), so I moved the call that had the potential to fail and all the code that assumes it passes into the "try" and left a no-op in the "catch".
Comment #11
mparker17A line in ConnectorTypeSwitcherTest...
... causes an PHPStan lint in Drupal 11 and PHPStan 2.1...
... but not Drupal 10 and PHPStan 1.12.
But making the recommended change (i.e.: deleting that assertInstanceOf line) causes new PHPStan lints to appear in Drupal 10 and PHPStan 1.12 (but not Drupal 11 and PHPStan 2.1)...
Ignoring the "will always evaluate to true" lint causes it to pass in Drupal 11 and PHPStan 2.1; but report that it didn't match an error in Drupal 10 and PHPStan 1.12; likewise ignoring the "Call to an undefined method" in D10/PHPStan1 will make it pass there, but report that it doesn't match in D11/PHPStan2.
Originally, I tried setting reportUnmatchedIgnoredErrors, but that felt wrong (we want to know when we've fixed something and don't have to ignore it anymore)
Asking in the Drupal Slack, @jonathan1055 came up with another solution: disabling the "phpstan (previous major)" job in
.gitlab-ci.yml. I'm okay with that, because I expect...... although at time-of-writing, it's not clear why the gitlab_template maintainers run a copy of phpstan for each variant (e.g.: why 2 phpstans, but only 1 phpcs, for example).
Comment #13
mparker17Merged to 9.0.x, merging to 8.0.x shortly.
Comment #15
mparker17Merged to 8.0.x. I'll update this issue when the code in this issue has been released.
Comment #17
mparker17The changes in this issue were released in elasticsearch_connector-9.0.0-alpha3, and elasticsearch_connector-8.0.0-alpha7