elasticsuite icon indicating copy to clipboard operation
elasticsuite copied to clipboard

DateMalformedStringException - Failed to parse time string (Ymd) at position 0 (Y) in module-elasticsuite-indices/Model/IndexStatusProvider.php:120

Open Tomasz-Silpion opened this issue 1 year ago • 4 comments

Preconditions

Rocky Linux release 9.4 (Blue Onyx), PHP 8.3.10, Elasticsearch 7.17.9

Magento Version : CE 2.4.7

ElasticSuite Version : 2.11.9

Environment : Production Mode

Third party modules : Yes. Too many and that's confidential.

Steps to reproduce

  1. In CLI type php bin/magentoindexer:reset catalogsearch_fulltext && php bin/magento indexer:reindex catalogsearch_fulltext
  2. Check the exception log tail -n 200 var/log/exception.log

Expected result

  1. No errors should be visible in exception log.

Actual result

  1. [2024-10-03T14:12:30.202727+00:00] main.ERROR: Error when loading/parsing statistics for index "magento2_default_catalog_category_20240729_111506" {"exception":"[object] (DateMalformedStringException(code: 0): Failed to parse time string (Ymd) at position 0 (Y): The timezone could not be found in the database at vendor/smile/elasticsuite/src/module-elasticsuite-indices/Model/IndexStatusProvider.php:120)"} [] is visible.

$today = new DateTime('Ymd'); line was introduced in https://github.com/Smile-SA/elasticsuite/blame/2.11.x/src/module-elasticsuite-indices/Model/IndexStatusProvider.php#L120C18-L120C50 within Zend libraries removal in #2818 but that line doesn't actually make any sense.

According to https://www.php.net/manual/en/class.datetime.php DateTime class should be called with $datetime string not the format (e.g. new DateTime(''now') or new DateTime('20231003')

Calling DateTime class with param Ymd is an obvious bug non compatible with any previous PHP version.

Tomasz-Silpion avatar Oct 03 '24 21:10 Tomasz-Silpion

Second param does not make any sense as well:

* @param DateTime|false $indexDate Index updated date.

then:

$day = new DateTime($indexDate);

so

{"exception":"[object] (TypeError(code: 0): DateTime::__construct(): Argument #1 ($datetime) must be of type string, DateTime given.

Why not just:

return ($today == $indexDate);

I don't know yet why this maybe deprecated method is being called in our case within latest module version but we suppose it stops our indexes from scheduled updates.

Tomasz-Silpion avatar Oct 09 '24 08:10 Tomasz-Silpion

I've just received confirmation that indexes are working as expected after these changes 🤷‍♂️

Here's our patch:

diff --git a/src/module-elasticsuite-indices/Model/IndexStatusProvider.php b/src/module-elasticsuite-indices/Model/IndexStatusProvider.php
index 541175b..1bba070 100644
--- a/src/module-elasticsuite-indices/Model/IndexStatusProvider.php
+++ b/src/module-elasticsuite-indices/Model/IndexStatusProvider.php
@@ -117,10 +117,9 @@ class IndexStatusProvider
         if (!empty($this->workingIndexers)) {
             foreach (array_keys($this->workingIndexers) as $indexKey) {
                 if (strpos((string) $indexName, $indexKey) !== false) {
-                    $today = new DateTime('Ymd');
-                    $day   = new DateTime($indexDate);
+                    $today = new DateTime('now');
 
-                    return ($today == $day);
+                    return ($today == $indexDate);
                 }
             }
         }

Tomasz-Silpion avatar Oct 09 '24 11:10 Tomasz-Silpion

Hello @Tomasz-Silpion,

I was not able to reproduce your issue with your steps to reproduce on the fresh Magento 2.4.7 CE/EE (Prod mode) with PHP 8.2.24/8.3.12, Elasticsearch 7.17.21 and with installed Elasticsuite 2.11.9.

After running php bin/magento indexer:reset catalogsearch_fulltext && php bin/magento indexer:reindex catalogsearch_fulltext commands I don't see any errors in the Magento logs linked with "Failed to parse time string (Ymd) at position 0 (Y)...".

Could you provide which Indices Name Pattern you are using in your environment?

ScreenShot Tool -20241009152036

BR, Vadym

vahonc avatar Oct 09 '24 12:10 vahonc

They are default ones:

{{Ymd}}_{{His}}

No idea what triggers the isRebuilding method in our envrionment but anyway, you see that the these:

$today = new DateTime('Ymd'); $day = new DateTime(DateTime $indexDate);

calls are invalid? https://www.php.net/manual/en/class.datetime.php

Construct time needs to be specified time string instead format or DateTime object.

Tomasz-Silpion avatar Oct 11 '24 01:10 Tomasz-Silpion