From 17b1c47201656d37fd37c0bc481a96e23da8032b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Wed, 5 Nov 2025 14:11:18 -0500 Subject: [PATCH] PHPLIB-1689 Make the Atlas Search exception more specific --- src/Exception/SearchNotSupportedException.php | 31 +++++++++++++++++++ src/Operation/Aggregate.php | 12 ++++++- src/Operation/CreateSearchIndexes.php | 12 ++++++- tests/Collection/CollectionFunctionalTest.php | 27 ++++++++++++++++ 4 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 src/Exception/SearchNotSupportedException.php diff --git a/src/Exception/SearchNotSupportedException.php b/src/Exception/SearchNotSupportedException.php new file mode 100644 index 000000000..2c1312b31 --- /dev/null +++ b/src/Exception/SearchNotSupportedException.php @@ -0,0 +1,31 @@ +getCode(), $e); + } + + public static function isSearchNotSupportedError(Throwable $e): bool + { + if (! $e instanceof ServerException) { + return false; + } + + return in_array($e->getCode(), [ + 59, // MongoDB 4 to 6, 7-community: no such command: 'createSearchIndexes' + 40324, // MongoDB 4 to 6: Unrecognized pipeline stage name: '$listSearchIndexes' + 115, // MongoDB 7-ent: Search index commands are only supported with Atlas. + 6047401, // MongoDB 7: $listSearchIndexes stage is only allowed on MongoDB Atlas + 31082, // MongoDB 8: Using Atlas Search Database Commands and the $listSearchIndexes aggregation stage requires additional configuration. + ], true); + } +} diff --git a/src/Operation/Aggregate.php b/src/Operation/Aggregate.php index b5da6470c..4d120f9c4 100644 --- a/src/Operation/Aggregate.php +++ b/src/Operation/Aggregate.php @@ -21,12 +21,14 @@ use MongoDB\Driver\Command; use MongoDB\Driver\CursorInterface; use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; +use MongoDB\Driver\Exception\ServerException; use MongoDB\Driver\ReadConcern; use MongoDB\Driver\ReadPreference; use MongoDB\Driver\Server; use MongoDB\Driver\Session; use MongoDB\Driver\WriteConcern; use MongoDB\Exception\InvalidArgumentException; +use MongoDB\Exception\SearchNotSupportedException; use MongoDB\Exception\UnexpectedValueException; use MongoDB\Exception\UnsupportedException; use MongoDB\Model\CodecCursor; @@ -233,7 +235,15 @@ public function execute(Server $server): CursorInterface $this->createCommandOptions(), ); - $cursor = $this->executeCommand($server, $command); + try { + $cursor = $this->executeCommand($server, $command); + } catch (ServerException $exception) { + if (SearchNotSupportedException::isSearchNotSupportedError($exception)) { + throw SearchNotSupportedException::create($exception); + } + + throw $exception; + } if (isset($this->options['codec'])) { return CodecCursor::fromCursor($cursor, $this->options['codec']); diff --git a/src/Operation/CreateSearchIndexes.php b/src/Operation/CreateSearchIndexes.php index d21ed9428..0b5b59573 100644 --- a/src/Operation/CreateSearchIndexes.php +++ b/src/Operation/CreateSearchIndexes.php @@ -19,8 +19,10 @@ use MongoDB\Driver\Command; use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; +use MongoDB\Driver\Exception\ServerException; use MongoDB\Driver\Server; use MongoDB\Exception\InvalidArgumentException; +use MongoDB\Exception\SearchNotSupportedException; use MongoDB\Exception\UnsupportedException; use MongoDB\Model\SearchIndexInput; @@ -83,7 +85,15 @@ public function execute(Server $server): array $cmd['comment'] = $this->options['comment']; } - $cursor = $server->executeCommand($this->databaseName, new Command($cmd)); + try { + $cursor = $server->executeCommand($this->databaseName, new Command($cmd)); + } catch (ServerException $exception) { + if (SearchNotSupportedException::isSearchNotSupportedError($exception)) { + throw SearchNotSupportedException::create($exception); + } + + throw $exception; + } /** @var object{indexesCreated: list} $result */ $result = current($cursor->toArray()); diff --git a/tests/Collection/CollectionFunctionalTest.php b/tests/Collection/CollectionFunctionalTest.php index 95659381c..31d965a99 100644 --- a/tests/Collection/CollectionFunctionalTest.php +++ b/tests/Collection/CollectionFunctionalTest.php @@ -13,6 +13,7 @@ use MongoDB\Driver\ReadPreference; use MongoDB\Driver\WriteConcern; use MongoDB\Exception\InvalidArgumentException; +use MongoDB\Exception\SearchNotSupportedException; use MongoDB\Exception\UnsupportedException; use MongoDB\Operation\Count; use MongoDB\Tests\CommandObserver; @@ -807,6 +808,32 @@ public function testListSearchIndexesInheritTypeMap(): void $this->assertIsArray($indexes[0]); } + public function testListSearchIndexesNotSupportedException(): void + { + if (self::isAtlas()) { + self::markTestSkipped('Atlas Search is supported on Atlas'); + } + + $collection = new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName()); + + $this->expectException(SearchNotSupportedException::class); + + $collection->listSearchIndexes(); + } + + public function testCreateSearchIndexNotSupportedException(): void + { + if (self::isAtlas()) { + self::markTestSkipped('Atlas Search is supported on Atlas'); + } + + $collection = new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName()); + + $this->expectException(SearchNotSupportedException::class); + + $collection->createSearchIndex(['mappings' => ['dynamic' => false]], ['name' => 'test-search-index']); + } + /** * Create data fixtures. */