From e1c899797dac400d035e1a8fac24705ddcf95402 Mon Sep 17 00:00:00 2001 From: james Date: Tue, 25 May 2021 13:51:58 +0100 Subject: [PATCH] feat: throw BulkInsertQueryException when there are any insert errors --- src/Connection.php | 12 +++-- src/Exceptions/BulkInsertQueryException.php | 57 +++++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 src/Exceptions/BulkInsertQueryException.php diff --git a/src/Connection.php b/src/Connection.php index 104122f..05d1723 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -3,6 +3,7 @@ namespace DesignMyNight\Elasticsearch; use Closure; +use DesignMyNight\Elasticsearch\Exceptions\BulkInsertQueryException; use DesignMyNight\Elasticsearch\Exceptions\QueryException; use Elasticsearch\ClientBuilder; use Illuminate\Database\Connection as BaseConnection; @@ -283,9 +284,10 @@ public function scroll(string $scrollId, string $scrollTimeout = '30s', int $lim /** * Run an insert statement against the database. * - * @param array $params - * @param array $bindings + * @param array $params + * @param array $bindings * @return bool + * @throws BulkInsertQueryException */ public function insert($params, $bindings = []) { @@ -295,7 +297,11 @@ public function insert($params, $bindings = []) Closure::fromCallable([$this->connection, 'bulk']) ); - return empty($result['errors']); + if (empty($result['errors'])) { + throw new BulkInsertQueryException($result); + } + + return true; } /** diff --git a/src/Exceptions/BulkInsertQueryException.php b/src/Exceptions/BulkInsertQueryException.php new file mode 100644 index 0000000..c11b181 --- /dev/null +++ b/src/Exceptions/BulkInsertQueryException.php @@ -0,0 +1,57 @@ +formatMessage($queryResult), 400); + } + + /** + * Format the error message. + * + * Takes the first {$this->errorLimit} bulk issues and concatenates them to a single string message + * + * @param array $result + * @return string + */ + private function formatMessage(array $result): string + { + $message = []; + + $items = array_filter($result['items'] ?? [], function(array $item): bool { + return $item['index'] && !empty($item['index']['error']); + }); + + $items = array_values($items); + + $totalErrors = count($items); + + // reduce to max limit + array_splice($items, 0, $this->errorLimit); + + $message[] = 'Bulk Insert Errors (' . 'Showing ' . count($items) . ' of ' . $totalErrors . '):'; + + foreach ($items as $item) { + $itemError = array_merge([ + '_id' => $item['_id'], + 'reason' => $item['error']['reason'], + ], $item['error']['caused_by'] ?? []); + + $message[] = implode(': ', $itemError); + } + + return implode(PHP_EOL, $message); + } +}