From 730d810b0dd24e80c1e88d56a5e6960363a25dbb Mon Sep 17 00:00:00 2001
From: Kir Shatrov <shatrov@me.com>
Date: Tue, 16 Jul 2019 21:22:42 +0100
Subject: [ActiveRecord] Superclass for aborted queries

---
 activerecord/lib/active_record/errors.rb                       | 10 +++++++---
 activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb |  1 +
 activerecord/test/cases/adapters/mysql2/transaction_test.rb    |  6 ++++--
 3 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/activerecord/lib/active_record/errors.rb b/activerecord/lib/active_record/errors.rb
index fa2df3a9ce..20cc987d6e 100644
--- a/activerecord/lib/active_record/errors.rb
+++ b/activerecord/lib/active_record/errors.rb
@@ -353,20 +353,24 @@ module ActiveRecord
   class IrreversibleOrderError < ActiveRecordError
   end
 
+  # Superclass for errors that have been aborted (either by client or server).
+  class QueryAborted < StatementInvalid
+  end
+
   # LockWaitTimeout will be raised when lock wait timeout exceeded.
   class LockWaitTimeout < StatementInvalid
   end
 
   # StatementTimeout will be raised when statement timeout exceeded.
-  class StatementTimeout < StatementInvalid
+  class StatementTimeout < QueryAborted
   end
 
   # QueryCanceled will be raised when canceling statement due to user request.
-  class QueryCanceled < StatementInvalid
+  class QueryCanceled < QueryAborted
   end
 
   # AdapterTimeout will be raised when database clients times out while waiting from the server.
-  class AdapterTimeout < StatementInvalid
+  class AdapterTimeout < QueryAborted
   end
 
   # UnknownAttributeReference is raised when an unknown and potentially unsafe
diff --git a/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb b/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb
index 6387f65b62..cfc1823773 100644
--- a/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/mysql2_adapter_test.rb
@@ -233,6 +233,7 @@ class Mysql2AdapterTest < ActiveRecord::Mysql2TestCase
     error = assert_raises(ActiveRecord::AdapterTimeout) do
       ActiveRecord::Base.connection.execute("SELECT SLEEP(2)")
     end
+    assert_kind_of ActiveRecord::QueryAborted, error
 
     assert_equal Mysql2::Error::TimeoutError, error.cause.class
   ensure
diff --git a/activerecord/test/cases/adapters/mysql2/transaction_test.rb b/activerecord/test/cases/adapters/mysql2/transaction_test.rb
index 52e283f247..2041cc308f 100644
--- a/activerecord/test/cases/adapters/mysql2/transaction_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/transaction_test.rb
@@ -92,7 +92,7 @@ module ActiveRecord
 
     test "raises StatementTimeout when statement timeout exceeded" do
       skip unless ActiveRecord::Base.connection.show_variable("max_execution_time")
-      assert_raises(ActiveRecord::StatementTimeout) do
+      error = assert_raises(ActiveRecord::StatementTimeout) do
         s = Sample.create!(value: 1)
         latch1 = Concurrent::CountDownLatch.new
         latch2 = Concurrent::CountDownLatch.new
@@ -117,10 +117,11 @@ module ActiveRecord
           thread.join
         end
       end
+      assert_kind_of ActiveRecord::QueryAborted, error
     end
 
     test "raises QueryCanceled when canceling statement due to user request" do
-      assert_raises(ActiveRecord::QueryCanceled) do
+      error = assert_raises(ActiveRecord::QueryCanceled) do
         s = Sample.create!(value: 1)
         latch = Concurrent::CountDownLatch.new
 
@@ -144,6 +145,7 @@ module ActiveRecord
           thread.join
         end
       end
+      assert_kind_of ActiveRecord::QueryAborted, error
     end
   end
 end
-- 
cgit v1.2.3