Skip to content

Commit db49de7

Browse files
committed
ACP2E-3892: [Mainline] Unpopulated pages are cached due to search engine errors
1 parent a1fc909 commit db49de7

File tree

6 files changed

+86
-60
lines changed

6 files changed

+86
-60
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\AdvancedSearch\Model\Client;
9+
10+
class ClientException extends \Exception
11+
{
12+
13+
}

app/code/Magento/Elasticsearch/ElasticAdapter/SearchAdapter/Adapter.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
namespace Magento\Elasticsearch\ElasticAdapter\SearchAdapter;
77

8+
use Magento\AdvancedSearch\Model\Client\ClientException;
89
use Magento\Elasticsearch\SearchAdapter\Aggregation\Builder as AggregationBuilder;
910
use Magento\Elasticsearch\SearchAdapter\ConnectionManager;
1011
use Magento\Elasticsearch\SearchAdapter\QueryContainerFactory;
@@ -111,8 +112,7 @@ public function query(RequestInterface $request)
111112
$rawResponse = $client->query($query);
112113
} catch (\Exception $e) {
113114
$this->logger->critical($e);
114-
// return empty search result in case an exception is thrown from Elasticsearch
115-
$rawResponse = self::$emptyRawResponse;
115+
throw new ClientException(__($e->getMessage()), $e->getCode(), $e);
116116
}
117117

118118
$rawDocuments = isset($rawResponse['hits']['hits']) ? $rawResponse['hits']['hits'] : [];

app/code/Magento/Elasticsearch8/SearchAdapter/Adapter.php

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace Magento\Elasticsearch8\SearchAdapter;
99

10+
use Magento\AdvancedSearch\Model\Client\ClientException;
1011
use Magento\Elasticsearch\SearchAdapter\Aggregation\Builder as AggregationBuilder;
1112
use Magento\Elasticsearch\SearchAdapter\ConnectionManager;
1213
use Magento\Elasticsearch\SearchAdapter\QueryContainerFactory;
@@ -50,21 +51,6 @@ class Adapter implements AdapterInterface
5051
*/
5152
private QueryContainerFactory $queryContainerFactory;
5253

53-
/**
54-
* Empty response from Elasticsearch
55-
*
56-
* @var array
57-
*/
58-
private static array $emptyRawResponse = [
59-
"hits" => [
60-
"hits" => []
61-
],
62-
"aggregations" => [
63-
"price_bucket" => [],
64-
"category_bucket" => ["buckets" => []],
65-
]
66-
];
67-
6854
/**
6955
* @var LoggerInterface
7056
*/
@@ -99,8 +85,9 @@ public function __construct(
9985
*
10086
* @param RequestInterface $request
10187
* @return QueryResponse
88+
* @throws ClientException
10289
*/
103-
public function query(RequestInterface $request) : QueryResponse
90+
public function query(RequestInterface $request): QueryResponse
10491
{
10592
$client = $this->connectionManager->getConnection();
10693
$query = $this->mapper->buildQuery($request);
@@ -111,8 +98,7 @@ public function query(RequestInterface $request) : QueryResponse
11198
$rawResponse = $client->query($query);
11299
} catch (\Exception $e) {
113100
$this->logger->critical($e);
114-
// return empty search result in case an exception is thrown from Elasticsearch
115-
$rawResponse = self::$emptyRawResponse;
101+
throw new ClientException($e->getMessage(), $e->getCode(), $e);
116102
}
117103

118104
$rawDocuments = $rawResponse['hits']['hits'] ?? [];

app/code/Magento/OpenSearch/SearchAdapter/Adapter.php

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2022 Adobe
4+
* All Rights Reserved.
55
*/
66
declare(strict_types=1);
77

88
namespace Magento\OpenSearch\SearchAdapter;
99

10+
use Magento\AdvancedSearch\Model\Client\ClientException;
1011
use Magento\Elasticsearch\SearchAdapter\Aggregation\Builder as AggregationBuilder;
1112
use Magento\Elasticsearch\SearchAdapter\ConnectionManager;
1213
use Magento\Elasticsearch\SearchAdapter\QueryContainerFactory;
@@ -27,54 +28,37 @@ class Adapter implements AdapterInterface
2728
*
2829
* @var Mapper
2930
*/
30-
private $mapper;
31+
private Mapper $mapper;
3132

3233
/**
3334
* @var ResponseFactory
3435
*/
35-
private $responseFactory;
36+
private ResponseFactory $responseFactory;
3637

3738
/**
3839
* @var ConnectionManager
3940
*/
40-
private $connectionManager;
41+
private ConnectionManager $connectionManager;
4142

4243
/**
4344
* @var AggregationBuilder
4445
*/
45-
private $aggregationBuilder;
46+
private AggregationBuilder $aggregationBuilder;
4647

4748
/**
4849
* @var QueryContainerFactory
4950
*/
50-
private $queryContainerFactory;
51-
52-
/**
53-
* Empty response from OpenSearch
54-
*
55-
* @var array
56-
*/
57-
private static $emptyRawResponse = [
58-
'hits' => [
59-
'hits' => []
60-
],
61-
'aggregations' => [
62-
'price_bucket' => [],
63-
'category_bucket' => [
64-
'buckets' => []
65-
]
66-
]
67-
];
51+
private QueryContainerFactory $queryContainerFactory;
6852

6953
/**
7054
* @var LoggerInterface
7155
*/
72-
private $logger;
56+
private LoggerInterface $logger;
7357

7458
/**
7559
* @var PageSizeProvider
7660
*/
77-
private $pageSizeProvider;
61+
private PageSizeProvider $pageSizeProvider;
7862

7963
/**
8064
* @param ConnectionManager $connectionManager
@@ -108,11 +92,11 @@ public function __construct(
10892
*
10993
* @param RequestInterface $request
11094
* @return QueryResponse
95+
* @throws ClientException
11196
*/
11297
public function query(RequestInterface $request) : QueryResponse
11398
{
11499
$client = $this->connectionManager->getConnection();
115-
116100
$query = $this->mapper->buildQuery($request);
117101
try {
118102
$maxPageSize = $this->pageSizeProvider->getMaxPageSize();
@@ -144,8 +128,7 @@ public function query(RequestInterface $request) : QueryResponse
144128
$rawResponse = $client->query($query);
145129
} catch (\Exception $e) {
146130
$this->logger->critical($e);
147-
// return empty search result in case an exception is thrown from OpenSearch
148-
$rawResponse = self::$emptyRawResponse;
131+
throw new ClientException($e->getMessage(), $e->getCode(), $e);
149132
} finally {
150133
if (isset($pitId)) {
151134
$client->closePointInTime(['body' => ['pit_id' => [$pitId]]]);

lib/internal/Magento/Framework/Search/AdapterInterface.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@
1616
*/
1717
interface AdapterInterface
1818
{
19+
public const EMPTY_RAW_RESPONSE = [
20+
'hits' => [
21+
'hits' => []
22+
],
23+
'aggregations' => [
24+
'price_bucket' => [],
25+
'category_bucket' => [
26+
'buckets' => []
27+
]
28+
]
29+
];
30+
1931
/**
2032
* Process Search Request
2133
*

lib/internal/Magento/Framework/Search/Search.php

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2015 Adobe
4+
* All Rights Reserved.
55
*/
66
namespace Magento\Framework\Search;
77

8+
use Magento\AdvancedSearch\Model\Client\ClientException;
9+
use Magento\Elasticsearch\SearchAdapter\Aggregation\Builder as AggregationBuilder;
10+
use Magento\Elasticsearch\SearchAdapter\ResponseFactory;
811
use Magento\Framework\Api\Search\SearchInterface;
912
use Magento\Framework\Api\Search\SearchCriteriaInterface;
1013
use Magento\Framework\App\ScopeResolverInterface;
@@ -18,39 +21,55 @@ class Search implements SearchInterface
1821
/**
1922
* @var Builder
2023
*/
21-
private $requestBuilder;
24+
private Builder $requestBuilder;
2225

2326
/**
2427
* @var ScopeResolverInterface
2528
*/
26-
private $scopeResolver;
29+
private ScopeResolverInterface $scopeResolver;
2730

2831
/**
2932
* @var SearchEngineInterface
3033
*/
31-
private $searchEngine;
34+
private SearchEngineInterface $searchEngine;
3235

3336
/**
3437
* @var SearchResponseBuilder
3538
*/
36-
private $searchResponseBuilder;
39+
private SearchResponseBuilder $searchResponseBuilder;
40+
41+
/**
42+
* @var ResponseFactory
43+
*/
44+
private ResponseFactory $responseFactory;
45+
46+
/**
47+
* @var AggregationBuilder
48+
*/
49+
private AggregationBuilder $aggregationBuilder;
3750

3851
/**
3952
* @param Builder $requestBuilder
4053
* @param ScopeResolverInterface $scopeResolver
4154
* @param SearchEngineInterface $searchEngine
4255
* @param SearchResponseBuilder $searchResponseBuilder
56+
* @param ResponseFactory $responseFactory
57+
* @param AggregationBuilder $aggregationBuilder
4358
*/
4459
public function __construct(
4560
Builder $requestBuilder,
4661
ScopeResolverInterface $scopeResolver,
4762
SearchEngineInterface $searchEngine,
48-
SearchResponseBuilder $searchResponseBuilder
63+
SearchResponseBuilder $searchResponseBuilder,
64+
ResponseFactory $responseFactory,
65+
AggregationBuilder $aggregationBuilder
4966
) {
5067
$this->requestBuilder = $requestBuilder;
5168
$this->scopeResolver = $scopeResolver;
5269
$this->searchEngine = $searchEngine;
5370
$this->searchResponseBuilder = $searchResponseBuilder;
71+
$this->responseFactory = $responseFactory;
72+
$this->aggregationBuilder = $aggregationBuilder;
5473
}
5574

5675
/**
@@ -81,11 +100,24 @@ public function search(SearchCriteriaInterface $searchCriteria)
81100
if (method_exists($this->requestBuilder, 'setSort')) {
82101
$this->requestBuilder->setSort($searchCriteria->getSortOrders());
83102
}
84-
$request = $this->requestBuilder->create();
85-
$searchResponse = $this->searchEngine->search($request);
103+
try {
104+
$request = $this->requestBuilder->create();
105+
$searchResponse = $this->searchEngine->search($request);
106+
$response = $this->searchResponseBuilder->build($searchResponse)
107+
->setSearchCriteria($searchCriteria);
108+
} catch (ClientException $e) {
109+
$aggregations = $this->aggregationBuilder->build($request, AdapterInterface::EMPTY_RAW_RESPONSE);
110+
$response = $this->responseFactory->create(
111+
[
112+
'documents' => [],
113+
'aggregations' => $aggregations,
114+
'total' => 0
115+
]
116+
);
117+
$response = $this->searchResponseBuilder->build($response)->setSearchCriteria($searchCriteria);
118+
}
86119

87-
return $this->searchResponseBuilder->build($searchResponse)
88-
->setSearchCriteria($searchCriteria);
120+
return $response;
89121
}
90122

91123
/**

0 commit comments

Comments
 (0)