From 3722c2b402499170695fa7bb5d0bd0abb8800e28 Mon Sep 17 00:00:00 2001 From: Lorin Thwaits Date: Fri, 4 Aug 2023 21:40:49 +0100 Subject: [PATCH] Incorporate rails/rails#48109 --- .../connection_adapters/trilogy_adapter.rb | 20 +++---- lib/activerecord-trilogy-adapter.rb | 1 - lib/trilogy_adapter/errors.rb | 54 ----------------- .../lost_connection_exception_translator.rb | 60 ------------------- .../trilogy_adapter_test.rb | 10 ++-- ...st_connection_exception_translator_test.rb | 55 ----------------- 6 files changed, 14 insertions(+), 186 deletions(-) delete mode 100644 lib/trilogy_adapter/errors.rb delete mode 100644 lib/trilogy_adapter/lost_connection_exception_translator.rb delete mode 100644 test/lib/trilogy_adapter/lost_connection_exception_translator_test.rb diff --git a/lib/active_record/connection_adapters/trilogy_adapter.rb b/lib/active_record/connection_adapters/trilogy_adapter.rb index 2c64755..c15726d 100644 --- a/lib/active_record/connection_adapters/trilogy_adapter.rb +++ b/lib/active_record/connection_adapters/trilogy_adapter.rb @@ -5,7 +5,6 @@ require "active_record/tasks/trilogy_database_tasks" require "active_record/connection_adapters/trilogy/database_statements" -require "trilogy_adapter/lost_connection_exception_translator" module ActiveRecord # ActiveRecord <= 6.1 support @@ -56,12 +55,21 @@ def resolve(config) # :nodoc: @resolver.resolve(config) end end + + module ::ActiveRecord + class QueryAborted < ::ActiveRecord::StatementInvalid + end + class AdapterTimeout < ::ActiveRecord::QueryAborted + end + end end module ConnectionAdapters class TrilogyAdapter < ::ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter ER_BAD_DB_ERROR = 1049 + ER_DBACCESS_DENIED_ERROR = 1044 ER_ACCESS_DENIED_ERROR = 1045 + ER_SERVER_SHUTDOWN = 1053 ADAPTER_NAME = "Trilogy" @@ -340,16 +348,6 @@ def default_timezone end end - def translate_exception(exception, message:, sql:, binds:) - if exception.is_a?(::Trilogy::TimeoutError) && !exception.error_code - return ActiveRecord::AdapterTimeout.new(message, sql: sql, binds: binds) - end - error_code = exception.error_code if exception.respond_to?(:error_code) - - ::TrilogyAdapter::LostConnectionExceptionTranslator. - new(exception, message, error_code).translate || super - end - def default_prepared_statements false end diff --git a/lib/activerecord-trilogy-adapter.rb b/lib/activerecord-trilogy-adapter.rb index d7a2359..19a9403 100644 --- a/lib/activerecord-trilogy-adapter.rb +++ b/lib/activerecord-trilogy-adapter.rb @@ -1,5 +1,4 @@ # frozen_string_literal: true require "active_record" -require "trilogy_adapter/errors" require "trilogy_adapter/railtie" diff --git a/lib/trilogy_adapter/errors.rb b/lib/trilogy_adapter/errors.rb deleted file mode 100644 index 0affcb1..0000000 --- a/lib/trilogy_adapter/errors.rb +++ /dev/null @@ -1,54 +0,0 @@ -# frozen_string_literal: true - -if ActiveRecord.version < ::Gem::Version.new('6.1.a') # ActiveRecord <= 6.0 support - module ::ActiveRecord - class QueryAborted < ::ActiveRecord::StatementInvalid - end - class AdapterTimeout < ::ActiveRecord::QueryAborted - end - end -end - -module TrilogyAdapter - module Errors - # ServerShutdown will be raised when the database server was shutdown. - class ServerShutdown < ::ActiveRecord::QueryAborted - end - - # ServerLost will be raised when the database connection was lost. - class ServerLost < ::ActiveRecord::QueryAborted - end - - # ServerGone will be raised when the database connection is gone. - class ServerGone < ::ActiveRecord::QueryAborted - end - - # BrokenPipe will be raised when a system process connection fails. - class BrokenPipe < ::ActiveRecord::QueryAborted - end - - # SocketError will be raised when Ruby encounters a network error. - class SocketError < ::ActiveRecord::QueryAborted - end - - # ConnectionResetByPeer will be raised when a network connection is closed - # outside the sytstem process. - class ConnectionResetByPeer < ::ActiveRecord::QueryAborted - end - - # ClosedConnection will be raised when the Trilogy encounters a closed - # connection. - class ClosedConnection < ::ActiveRecord::QueryAborted - end - - # InvalidSequenceId will be raised when Trilogy ecounters an invalid sequence - # id. - class InvalidSequenceId < ::ActiveRecord::QueryAborted - end - - # UnexpectedPacket will be raised when Trilogy ecounters an unexpected - # response packet. - class UnexpectedPacket < ::ActiveRecord::QueryAborted - end - end -end diff --git a/lib/trilogy_adapter/lost_connection_exception_translator.rb b/lib/trilogy_adapter/lost_connection_exception_translator.rb deleted file mode 100644 index 9c4623c..0000000 --- a/lib/trilogy_adapter/lost_connection_exception_translator.rb +++ /dev/null @@ -1,60 +0,0 @@ -# frozen_string_literal: true - -module TrilogyAdapter - class LostConnectionExceptionTranslator - attr_reader :exception, :message, :error_number - - def initialize(exception, message, error_number) - @exception = exception - @message = message - @error_number = error_number - end - - def translate - translate_database_exception || translate_ruby_exception || translate_trilogy_exception - end - - private - ER_SERVER_SHUTDOWN = 1053 - CR_SERVER_LOST = 2013 - CR_SERVER_LOST_EXTENDED = 2055 - CR_SERVER_GONE_ERROR = 2006 - - def translate_database_exception - case error_number - when ER_SERVER_SHUTDOWN - Errors::ServerShutdown.new(message) - when CR_SERVER_LOST, CR_SERVER_LOST_EXTENDED - Errors::ServerLost.new(message) - when CR_SERVER_GONE_ERROR - Errors::ServerGone.new(message) - end - end - - def translate_ruby_exception - case exception - when Errno::EPIPE - Errors::BrokenPipe.new(message) - when SocketError, IOError - Errors::SocketError.new(message) - when Trilogy::ConnectionError - if message.match?(/Connection reset by peer/) - Errors::ConnectionResetByPeer.new(message) - end - end - end - - def translate_trilogy_exception - return unless exception.is_a?(Trilogy::Error) - - case message - when /TRILOGY_CLOSED_CONNECTION/ - Errors::ClosedConnection.new(message) - when /TRILOGY_INVALID_SEQUENCE_ID/ - Errors::InvalidSequenceId.new(message) - when /TRILOGY_UNEXPECTED_PACKET/ - Errors::UnexpectedPacket.new(message) - end - end - end -end diff --git a/test/lib/active_record/connection_adapters/trilogy_adapter_test.rb b/test/lib/active_record/connection_adapters/trilogy_adapter_test.rb index 0f6c4b5..ed81c96 100644 --- a/test/lib/active_record/connection_adapters/trilogy_adapter_test.rb +++ b/test/lib/active_record/connection_adapters/trilogy_adapter_test.rb @@ -46,7 +46,7 @@ class ActiveRecord::ConnectionAdapters::TrilogyAdapterTest < TestCase test ".new_client on access denied error" do configuration = @configuration.merge(username: "unknown") - assert_raises ActiveRecord::DatabaseConnectionError do + assert_raises Trilogy::QueryError do @adapter.class.new_client(configuration) end end @@ -457,7 +457,7 @@ class Post < ActiveRecord::Base; end server_shutdown_error.instance_variable_set(:@error_code, 1053) mock_connection.expect(:query, nil) { raise server_shutdown_error } - assert_raises(TrilogyAdapter::Errors::ServerShutdown) do + assert_raises(ActiveRecord::StatementInvalid) do adapter.execute "SELECT * FROM posts;" end @@ -772,13 +772,13 @@ class Post < ActiveRecord::Base; end assert_equal 123, @adapter.send(:error_number, exception) end - test "read timeout raises ActiveRecord::AdapterTimeout" do + test "read timeout raises ActiveRecord::StatementInvalid" do ActiveRecord::Base.establish_connection(@configuration.merge("read_timeout" => 1)) - error = assert_raises(ActiveRecord::AdapterTimeout) do + error = assert_raises(ActiveRecord::StatementInvalid) do ActiveRecord::Base.connection.execute("SELECT SLEEP(2)") end - assert_kind_of ActiveRecord::QueryAborted, error + assert_kind_of ActiveRecord::StatementInvalid, error assert_equal Trilogy::TimeoutError, error.cause.class end diff --git a/test/lib/trilogy_adapter/lost_connection_exception_translator_test.rb b/test/lib/trilogy_adapter/lost_connection_exception_translator_test.rb deleted file mode 100644 index e068744..0000000 --- a/test/lib/trilogy_adapter/lost_connection_exception_translator_test.rb +++ /dev/null @@ -1,55 +0,0 @@ -# frozen_string_literal: true - -require "test_helper" - -class TrilogyAdapter::LostConnectionExceptionTranslatorTest < TestCase - test "#translate returns appropriate TrilogyAdapter error for Trilogy exceptions" do - translator = TrilogyAdapter::LostConnectionExceptionTranslator.new( - Trilogy::ProtocolError.new, - "ER_SERVER_SHUTDOWN 1053", - 1053 - ) - - assert_kind_of(TrilogyAdapter::Errors::ServerShutdown, translator.translate) - end - - test "#translate returns nil for Trilogy exceptions when the error code is not given" do - translator = TrilogyAdapter::LostConnectionExceptionTranslator.new( - Trilogy::ProtocolError.new, - "ER_SERVER_SHUTDOWN 1053", - nil - ) - - assert_nil translator.translate - end - - test "#translate returns appropriate TrilogyAdapter error for Ruby exceptions" do - translator = TrilogyAdapter::LostConnectionExceptionTranslator.new( - SocketError.new, - "Failed to open TCP connection", - nil - ) - - assert_kind_of(TrilogyAdapter::Errors::SocketError, translator.translate) - end - - test "#translate returns appropriate TrilogyAdapter error for lost connection Trilogy exceptions" do - translator = TrilogyAdapter::LostConnectionExceptionTranslator.new( - Trilogy::BaseError.new, - "TRILOGY_UNEXPECTED_PACKET", - nil - ) - - assert_kind_of(TrilogyAdapter::Errors::UnexpectedPacket, translator.translate) - end - - test "#translate returns nil for non-lost connection exceptions" do - translator = TrilogyAdapter::LostConnectionExceptionTranslator.new( - Trilogy::BaseError.new, - "Something bad happened but it wasn't a lost connection so...", - nil - ) - - assert_nil translator.translate - end -end