diff --git a/src/Documents/DocumentManager.php b/src/Documents/DocumentManager.php index bc32481..50ad5f4 100644 --- a/src/Documents/DocumentManager.php +++ b/src/Documents/DocumentManager.php @@ -2,6 +2,7 @@ namespace ElasticAdapter\Documents; +use ElasticAdapter\ElasticException; use ElasticAdapter\Search\SearchRequest; use ElasticAdapter\Search\SearchResponse; use Elasticsearch\Client; @@ -44,11 +45,32 @@ public function index( $params['body'][] = $document->getContent(); } - $this->client->bulk($params); + $response = $this->client->bulk($params); + + if ($response['errors'] ?? false) { + $error = $this->getFirstErrorFromResponse($response); + + throw new ElasticException( + sprintf('%s: %s', $error['type'], $error['reason']) + ); + } return $this; } + protected function getFirstErrorFromResponse(array $response) + { + foreach ($response['items'] as $item) { + $result = reset($item); + + if (! isset($result['error'])) { + continue; + } + + return $result['error']; + } + } + /** * @param Document[] $documents */ diff --git a/src/ElasticException.php b/src/ElasticException.php new file mode 100644 index 0000000..fdd6541 --- /dev/null +++ b/src/ElasticException.php @@ -0,0 +1,7 @@ +indices->exists([ diff --git a/tests/Unit/Documents/DocumentManagerTest.php b/tests/Unit/Documents/DocumentManagerTest.php index 1449440..81d52f2 100644 --- a/tests/Unit/Documents/DocumentManagerTest.php +++ b/tests/Unit/Documents/DocumentManagerTest.php @@ -4,6 +4,7 @@ use ElasticAdapter\Documents\Document; use ElasticAdapter\Documents\DocumentManager; +use ElasticAdapter\ElasticException; use ElasticAdapter\Search\SearchRequest; use ElasticAdapter\Search\SearchResponse; use Elasticsearch\Client; @@ -235,4 +236,49 @@ public function test_documents_can_be_found(): void $this->assertSame(1, $response->getHitsTotal()); $this->assertEquals(new Document('1', ['content' => 'foo']), $response->getHits()[0]->getDocument()); } + + public function test_exception_is_thrown_when_index_response_contains_error(): void + { + $this->client + ->expects($this->once()) + ->method('bulk') + ->with([ + 'index' => 'test', + 'refresh' => 'false', + 'body' => [ + ['index' => ['_id' => '1']], + ['title' => 'Doc 1'], + ], + ])->willReturn([ + 'took' => 0, + 'errors' => true, + 'items' => [ + [ + 'index' => [ + '_index' => 'test', + '_type' => '_doc', + '_id' => '1', + 'status' => 400, + 'error' => [ + 'type' => "mapper_parsing_exception", + 'reason' => "failed to parse field [title] of type [text] in document with id '1'. Preview of field's value: 'Doc 1'", + 'caused_by' => [ + 'type' => 'illegal_state_exception', + 'reason' => "Can't get text on a START_OBJECT at 1:362", + ], + ], + ], + ], + ], + ]); + + $this->expectException(ElasticException::class); + $this->expectExceptionMessage( + "mapper_parsing_exception: failed to parse field [title] of type [text] in document with id '1'. Preview of field's value: 'Doc 1'" + ); + + $this->documentManager->index('test', [ + new Document('1', ['title' => 'Doc 1']), + ], false); + } }