Skip to content

Commit 8bd78be

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

File tree

4 files changed

+44
-41
lines changed

4 files changed

+44
-41
lines changed

app/code/Magento/Catalog/Block/Product/ListProduct.php

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use Magento\Framework\Url\Helper\Data;
2929
use Magento\Framework\App\ObjectManager;
3030
use Magento\Catalog\Helper\Output as OutputHelper;
31+
use Magento\Framework\App\Response\Http as ResponseHttp;
3132

3233
/**
3334
* Product list
@@ -88,6 +89,7 @@ class ListProduct extends AbstractProduct implements IdentityInterface
8889
* @param array $data
8990
* @param OutputHelper|null $outputHelper
9091
* @param SpecialPriceBulkResolverInterface|null $specialPriceBulkResolver
92+
* @param ResponseHttp|null $response
9193
*/
9294
public function __construct(
9395
Context $context,
@@ -208,14 +210,16 @@ protected function _beforeToHtml()
208210
$this->addToolbarBlock($collection);
209211

210212
if (!$collection->isLoaded()) {
211-
$collection->load();
212-
}
213-
214-
$categoryId = $this->getLayer()->getCurrentCategory()->getId();
215-
216-
if ($categoryId) {
217-
foreach ($collection as $product) {
218-
$product->setData('category_id', $categoryId);
213+
try {
214+
$products = $collection->getItems();
215+
if ($categoryId = $this->getLayer()->getCurrentCategory()->getId()) {
216+
foreach ($products as $product) {
217+
$product->setData('category_id', $categoryId);
218+
}
219+
}
220+
} catch (\Throwable) {
221+
$this->setData('has_error', true);
222+
$this->_productCollection = [];
219223
}
220224
}
221225

app/code/Magento/Catalog/view/frontend/templates/product/list.phtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ $_productCollection = $block->getLoadedProductCollection();
2020
/** @var \Magento\Catalog\Helper\Output $_helper */
2121
$_helper = $block->getData('outputHelper');
2222
?>
23-
<?php if (!$_productCollection->count()): ?>
23+
<?php if ($block->getData('has_error') || !$_productCollection->count()): ?>
2424
<div class="message info empty">
2525
<div><?= $escaper->escapeHtml(__('We can\'t find products matching the selection.')) ?></div>
2626
</div>

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

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
namespace Magento\Framework\Search;
77

88
use Magento\AdvancedSearch\Model\Client\ClientException;
9-
use Magento\Elasticsearch\SearchAdapter\Aggregation\Builder as AggregationBuilder;
109
use Magento\Elasticsearch\SearchAdapter\ResponseFactory;
1110
use Magento\Framework\Api\Search\SearchInterface;
1211
use Magento\Framework\Api\Search\SearchCriteriaInterface;
1312
use Magento\Framework\App\ScopeResolverInterface;
13+
use Magento\Framework\Exception\LocalizedException;
1414
use Magento\Framework\Search\Request\Builder;
1515

1616
/**
@@ -43,37 +43,30 @@ class Search implements SearchInterface
4343
*/
4444
private ResponseFactory $responseFactory;
4545

46-
/**
47-
* @var AggregationBuilder
48-
*/
49-
private AggregationBuilder $aggregationBuilder;
50-
5146
/**
5247
* @param Builder $requestBuilder
5348
* @param ScopeResolverInterface $scopeResolver
5449
* @param SearchEngineInterface $searchEngine
5550
* @param SearchResponseBuilder $searchResponseBuilder
5651
* @param ResponseFactory $responseFactory
57-
* @param AggregationBuilder $aggregationBuilder
5852
*/
5953
public function __construct(
6054
Builder $requestBuilder,
6155
ScopeResolverInterface $scopeResolver,
6256
SearchEngineInterface $searchEngine,
6357
SearchResponseBuilder $searchResponseBuilder,
64-
ResponseFactory $responseFactory,
65-
AggregationBuilder $aggregationBuilder
58+
ResponseFactory $responseFactory
6659
) {
6760
$this->requestBuilder = $requestBuilder;
6861
$this->scopeResolver = $scopeResolver;
6962
$this->searchEngine = $searchEngine;
7063
$this->searchResponseBuilder = $searchResponseBuilder;
7164
$this->responseFactory = $responseFactory;
72-
$this->aggregationBuilder = $aggregationBuilder;
7365
}
7466

7567
/**
7668
* @inheritdoc
69+
* @throws LocalizedException
7770
*/
7871
public function search(SearchCriteriaInterface $searchCriteria)
7972
{
@@ -106,15 +99,7 @@ public function search(SearchCriteriaInterface $searchCriteria)
10699
$response = $this->searchResponseBuilder->build($searchResponse)
107100
->setSearchCriteria($searchCriteria);
108101
} 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);
102+
throw new LocalizedException(__('Could not perform search'), $e, $e->getCode());
118103
}
119104

120105
return $response;

lib/internal/Magento/Framework/View/Layout.php

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

@@ -11,10 +11,16 @@
1111
use Magento\Framework\App\State as AppState;
1212
use Magento\Framework\Cache\FrontendInterface;
1313
use Magento\Framework\Event\ManagerInterface;
14-
use Magento\Framework\Exception\LocalizedException;
14+
use Magento\Framework\App\Response\Http as ResponseHttp;
1515
use Magento\Framework\Message\ManagerInterface as MessageManagerInterface;
1616
use Magento\Framework\Serialize\SerializerInterface;
17+
use Magento\Framework\View\Design\Theme\ResolverInterface;
18+
use Magento\Framework\View\Layout\Data\Structure;
1719
use Magento\Framework\View\Layout\Element;
20+
use Magento\Framework\View\Layout\GeneratorPool;
21+
use Magento\Framework\View\Layout\ProcessorFactory;
22+
use Magento\Framework\View\Layout\Reader\ContextFactory;
23+
use Magento\Framework\View\Layout\ReaderPool;
1824
use Psr\Log\LoggerInterface as Logger;
1925

2026
/**
@@ -183,21 +189,27 @@ class Layout extends \Magento\Framework\Simplexml\Config implements \Magento\Fra
183189
private $cacheLifetime;
184190

185191
/**
186-
* @param Layout\ProcessorFactory $processorFactory
192+
* @var ResponseHttp
193+
*/
194+
private ResponseHttp $response;
195+
196+
/**
197+
* @param ProcessorFactory $processorFactory
187198
* @param ManagerInterface $eventManager
188-
* @param Layout\Data\Structure $structure
199+
* @param Structure $structure
189200
* @param MessageManagerInterface $messageManager
190-
* @param Design\Theme\ResolverInterface $themeResolver
191-
* @param Layout\ReaderPool $readerPool
192-
* @param Layout\GeneratorPool $generatorPool
201+
* @param ResolverInterface $themeResolver
202+
* @param ReaderPool $readerPool
203+
* @param GeneratorPool $generatorPool
193204
* @param FrontendInterface $cache
194-
* @param Layout\Reader\ContextFactory $readerContextFactory
205+
* @param ContextFactory $readerContextFactory
195206
* @param Layout\Generator\ContextFactory $generatorContextFactory
196-
* @param \Magento\Framework\App\State $appState
197-
* @param \Psr\Log\LoggerInterface $logger
207+
* @param State $appState
208+
* @param LoggerInterface $logger
198209
* @param bool $cacheable
199210
* @param SerializerInterface|null $serializer
200211
* @param int|null $cacheLifetime
212+
* @param ResponseHttp|null $response
201213
*/
202214
public function __construct(
203215
Layout\ProcessorFactory $processorFactory,
@@ -214,12 +226,13 @@ public function __construct(
214226
Logger $logger,
215227
$cacheable = true,
216228
?SerializerInterface $serializer = null,
217-
?int $cacheLifetime = null
229+
?int $cacheLifetime = null,
230+
?ResponseHttp $response = null
218231
) {
219232
$this->_elementClass = \Magento\Framework\View\Layout\Element::class;
220233
$this->_renderingOutput = new \Magento\Framework\DataObject();
221234
$this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
222-
235+
$this->response = $response ?: ObjectManager::getInstance()->get(ResponseHttp::class);
223236
$this->_processorFactory = $processorFactory;
224237
$this->_eventManager = $eventManager;
225238
$this->structure = $structure;
@@ -557,6 +570,7 @@ public function renderNonCachedElement($name)
557570
$result = $this->_renderContainer($name, false);
558571
}
559572
} catch (\Exception $e) {
573+
$this->response->setNoCacheHeaders();
560574
if ($this->appState->getMode() === AppState::MODE_DEVELOPER) {
561575
throw $e;
562576
}

0 commit comments

Comments
 (0)