From 7d1310d1898ba90d629994e9ca48924c2a1869a0 Mon Sep 17 00:00:00 2001
From: Jamis Buck <jamis.buck@mongodb.com>
Date: Fri, 29 Mar 2024 10:20:36 -0600
Subject: [PATCH] work around the new exception class not being present in
 older driver versions

---
 gemfiles/driver_stable.gemfile  |  2 +-
 lib/mongoid/clients/sessions.rb | 18 +++++++++++++++++-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/gemfiles/driver_stable.gemfile b/gemfiles/driver_stable.gemfile
index f28c5be54a..8df367525e 100644
--- a/gemfiles/driver_stable.gemfile
+++ b/gemfiles/driver_stable.gemfile
@@ -1,7 +1,7 @@
 # rubocop:todo all
 source "https://rubygems.org"
 
-gem 'mongo', git: "https://github.com/mongodb/mongo-ruby-driver", branch: '2.18-stable'
+gem 'mongo', git: "https://github.com/mongodb/mongo-ruby-driver", branch: '2.19-stable'
 
 gem 'actionpack'
 
diff --git a/lib/mongoid/clients/sessions.rb b/lib/mongoid/clients/sessions.rb
index 16aac83ad0..8774b680b5 100644
--- a/lib/mongoid/clients/sessions.rb
+++ b/lib/mongoid/clients/sessions.rb
@@ -90,7 +90,7 @@ def transaction(options = {}, session_options: {})
               session.start_transaction(options)
               yield
               commit_transaction(session)
-            rescue Mongo::Error::TransactionsNotSupported
+            rescue *transactions_not_supported_exceptions
               raise Mongoid::Errors::TransactionsNotSupported
             rescue Mongoid::Errors::Rollback
               abort_transaction(session)
@@ -152,6 +152,22 @@ def after_rollback(*args, &block)
 
         private
 
+        # Driver version 2.20 introduced a new exception for reporting that
+        # transactions are not supported. Prior to that, the condition was
+        # discovered by the rescue clause falling through to a different
+        # exception.
+        #
+        # This method ensures that Mongoid continues to work with older driver
+        # versions, by only returning the new exception.
+        #
+        # Once support is removed for all versions prior to 2.20.0, we can
+        # replace this method.
+        def transactions_not_supported_exceptions
+          return nil unless defined? Mongo::Error::TransactionsNotSupported
+
+          Mongo::Error::TransactionsNotSupported
+        end
+
         # @return [ Mongo::Session ] Session for the current client.
         def _session
           Threaded.get_session(client: persistence_context.client)