diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index b3b46625b..be9b7cd48 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -16,6 +16,7 @@
+
diff --git a/src/Exception/AtlasSearchNotSupportedException.php b/src/Exception/AtlasSearchNotSupportedException.php
new file mode 100644
index 000000000..b65b1620b
--- /dev/null
+++ b/src/Exception/AtlasSearchNotSupportedException.php
@@ -0,0 +1,40 @@
+getCode() === 31082 ? $e->getMessage() : 'Using Atlas Search Database Commands and the $listSearchIndexes aggregation stage requires additional configuration. Please connect to Atlas or an AtlasCLI local deployment to enable. For more information on how to connect, see https://dochub.mongodb.org/core/atlas-cli-deploy-local-reqs';
+
+ return new self($message, $e->getCode(), $e);
+ }
+
+ /** @internal */
+ public static function isAtlasSearchNotSupportedError(Throwable $e): bool
+ {
+ if (! $e instanceof ServerException) {
+ return false;
+ }
+
+ return match ($e->getCode()) {
+ // MongoDB 8: Using Atlas Search Database Commands and the $listSearchIndexes aggregation stage requires additional configuration.
+ 31082 => true,
+ // MongoDB 7: $listSearchIndexes stage is only allowed on MongoDB Atlas
+ 6047401 => true,
+ // MongoDB 7-ent: Search index commands are only supported with Atlas.
+ 115 => true,
+ // MongoDB 4 to 6, 7-community
+ 59 => 'no such command: \'createSearchIndexes\'' === $e->getMessage(),
+ // MongoDB 4 to 6
+ 40324 => 'Unrecognized pipeline stage name: \'$listSearchIndexes\'' === $e->getMessage(),
+ // Not an Atlas Search error
+ default => false,
+ };
+ }
+}
diff --git a/src/Operation/Aggregate.php b/src/Operation/Aggregate.php
index b5da6470c..6827bb07f 100644
--- a/src/Operation/Aggregate.php
+++ b/src/Operation/Aggregate.php
@@ -21,11 +21,13 @@
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\AtlasSearchNotSupportedException;
use MongoDB\Exception\InvalidArgumentException;
use MongoDB\Exception\UnexpectedValueException;
use MongoDB\Exception\UnsupportedException;
@@ -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 (AtlasSearchNotSupportedException::isAtlasSearchNotSupportedError($exception)) {
+ throw AtlasSearchNotSupportedException::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..2738b7291 100644
--- a/src/Operation/CreateSearchIndexes.php
+++ b/src/Operation/CreateSearchIndexes.php
@@ -19,7 +19,9 @@
use MongoDB\Driver\Command;
use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Exception\ServerException;
use MongoDB\Driver\Server;
+use MongoDB\Exception\AtlasSearchNotSupportedException;
use MongoDB\Exception\InvalidArgumentException;
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 (AtlasSearchNotSupportedException::isAtlasSearchNotSupportedError($exception)) {
+ throw AtlasSearchNotSupportedException::create($exception);
+ }
+
+ throw $exception;
+ }
/** @var object{indexesCreated: list