private async Task IndexAsync( ISearchIndexClientWrapper indexClient, IReadOnlyCollection <IndexAction <KeyedDocument> > batch) { if (batch.Count == 0) { return; } if (batch.Count > _options.Value.AzureSearchBatchSize) { throw new ArgumentException("The provided batch is too large."); } _logger.LogInformation( "Pushing batch of {BatchSize} to index {IndexName}.", batch.Count, indexClient.IndexName); IList <IndexingResult> indexingResults = null; Exception innerException = null; var stopwatch = Stopwatch.StartNew(); try { var batchResults = await indexClient.Documents.IndexAsync(new IndexBatch <KeyedDocument>(batch)); indexingResults = batchResults.Results; stopwatch.Stop(); _telemetryService.TrackIndexPushSuccess(indexClient.IndexName, batch.Count, stopwatch.Elapsed); } catch (IndexBatchException ex) { stopwatch.Stop(); _telemetryService.TrackIndexPushFailure(indexClient.IndexName, batch.Count, stopwatch.Elapsed); _logger.LogError( 0, ex, "An exception was thrown while sending documents to index {IndexName}.", indexClient.IndexName); indexingResults = ex.IndexingResults; innerException = ex; } catch (CloudException ex) when(ex.Response.StatusCode == HttpStatusCode.RequestEntityTooLarge && batch.Count > 1) { stopwatch.Stop(); _telemetryService.TrackIndexPushSplit(indexClient.IndexName, batch.Count); var halfCount = batch.Count / 2; var halfA = batch.Take(halfCount).ToList(); var halfB = batch.Skip(halfCount).ToList(); _logger.LogWarning( 0, ex, "The request body for a batch of {BatchSize} was too large. Splitting into two batches of size " + "{HalfA} and {HalfB}.", batch.Count, halfA.Count, halfB.Count); await IndexAsync(indexClient, halfA); await IndexAsync(indexClient, halfB); } if (indexingResults != null) { const int errorsToLog = 5; var errorCount = 0; foreach (var result in indexingResults) { if (!result.Succeeded) { if (errorCount < errorsToLog) { _logger.LogError( "Indexing document with key {Key} failed for index {IndexName}. {StatusCode}: {ErrorMessage}", result.Key, indexClient.IndexName, result.StatusCode, result.ErrorMessage); } errorCount++; } } if (errorCount > 0) { _logger.LogError( "{ErrorCount} errors were found when indexing a batch for index {IndexName}. {LoggedErrors} were logged.", errorCount, indexClient.IndexName, Math.Min(errorCount, errorsToLog)); throw new InvalidOperationException( $"Errors were found when indexing a batch. Up to {errorsToLog} errors get logged.", innerException); } } }