Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRAFT Allows indexing to continue if an index error occurs, and add log. #3

Draft
wants to merge 4 commits into
base: pulls/v3-backport
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/Admin/SearchAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,11 @@ private function buildIndexedDocumentsList(): ArrayList
$query->where('ShowInSearch = 1');
}

// where appropriate, make sure we only show database total for this index
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On a project with indexing for subsites, it was noted that the total documents in the database didn't take into account the subsite (and index) to which the document related to.

if ($class::singleton()->hasField('Subsite')) {
$query->where(sprintf('SubsiteID = %s', $index));
}

$this->extend('updateQuery', $query, $data);
$localCount += $query->count();
}
Expand Down
58 changes: 58 additions & 0 deletions src/DataObject/DataObjectDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Exception;
use InvalidArgumentException;
use LogicException;
use Psr\Log\LoggerInterface;
use SilverStripe\Core\Config\Configurable;
use SilverStripe\Core\Extensible;
use SilverStripe\Core\Injector\Injectable;
Expand Down Expand Up @@ -85,17 +86,35 @@ class DataObjectDocument implements

private bool $shouldFallbackToLatestVersion = false;

/**
* This will be set automatically
*
* @var LoggerInterface
*/
private $logger;

private static array $dependencies = [
'IndexService' => '%$' . IndexingInterface::class,
'PageCrawler' => '%$' . PageCrawler::class,
'Configuration' => '%$' . IndexConfiguration::class,
'Logger' => '%$' . LoggerInterface::class,
];

public function __construct(DataObject $dataObject)
{
$this->setDataObject($dataObject);
}

/**
* @param LoggerInterface $logger
* @return $this
*/
public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
return $this;
}

public function getIdentifier(): string
{
$type = str_replace('\\', '_', $this->getDataObject()->baseClass());
Expand Down Expand Up @@ -594,6 +613,24 @@ private function getFieldTuple(Field $field): array
return [null, $this->resolveField($field->getSearchFieldName())];
}

/**
* Returns an array containing the database records of
* a DataObject instance according to the given Document.
*
* @return array
*/
private function getDocumentRecordFields(): array
{
$dataObject = $this->getDataObject();

return [
'ID' => $dataObject->ID,
'ClassName' => $dataObject->ClassName,
'Title' => $dataObject->Title,
'URL' => method_exists($dataObject, 'link') ? $dataObject->link() : '',
];
}

public function __serialize(): array
{
return [
Expand Down Expand Up @@ -665,4 +702,25 @@ public function onRemoveFromSearchIndexes(string $event): void
}
}

/**
* @param array $error The errors associated with a document
* @param string $indexName The name of the index the document was being added to
* @return void
*/
public function onErrorFromSearchIndex($error, $indexName): void
{
$recordFields = $this->getDocumentRecordFields();

$message = [
'Message' => sprintf('Unable to index a document to %s', $indexName),
'Title' => $recordFields['Title'],
'URL' => $recordFields['URL'],
'ID' => $recordFields['ID'],
'ClassName' => $recordFields['ClassName'],
'Error' => implode('|', array_values($error)),
];

$this->logger->error(json_encode($message));
}

}
31 changes: 30 additions & 1 deletion src/Service/EnterpriseSearch/EnterpriseSearchService.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,15 @@ public function addDocuments(array $documents): array
$processedIds = [];

foreach ($documentMap as $indexName => $docsToAdd) {
// TEMP change to force an error
$docsToAdd[0]['fruit'] = 'TEST'; // expecting an integer

$response = $this->getClient()->appSearch()
->indexDocuments(new IndexDocuments(static::environmentizeIndex($indexName), $docsToAdd))
->asArray();

$this->handleError($response);
// log error, but continue to index
$this->handleErrorAndContinue($response, $indexName, $documents);

// Grab all the ID values, and also cast them to string
$processedIds += array_map('strval', array_column($response, 'id'));
Expand Down Expand Up @@ -506,6 +510,31 @@ private function handleError(?array $responseBody): void
));
}


/**
* Handle index errors, and log, but don't throw exception and allow to continue indexing.
*
* @param array|null $responseBody
* @param string $indexName
* @param array $documents
* @return void
*/
protected function handleErrorAndContinue(?array $responseBody, string $indexName, array $documents): void
{
if (!is_array($responseBody)) {
return;
}

foreach ($responseBody as $key => $response) {
if (!$response['errors']) {
return;
}

$document = $documents[$key];
$document->onErrorFromSearchIndex($response['errors'], $indexName);
}
}

/**
* @param Field[] $fields
*/
Expand Down