diff --git a/lib/active_record/connection_adapters/cockroachdb_adapter.rb b/lib/active_record/connection_adapters/cockroachdb_adapter.rb index f70242ce..4e376531 100644 --- a/lib/active_record/connection_adapters/cockroachdb_adapter.rb +++ b/lib/active_record/connection_adapters/cockroachdb_adapter.rb @@ -217,16 +217,33 @@ def check_version # :nodoc: end end - def initialize(...) + def configure_connection(...) super # This rescue flow appears in new_client, but it is needed here as well # since Cockroach will sometimes not raise until a query is made. + # + # See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/337#issuecomment-2328419453 + # + # The error conditions used to differ from the ones in new_client, but + # the reasons why are no longer relevant. We keep this in sync with new_client + # even though some conditions might never be checked. + # + # See https://github.com/cockroachdb/activerecord-cockroachdb-adapter/pull/229 + # + # We have to rescue `ActiveRecord::StatementInvalid` instead of `::PG::Error` + # here as the error has already been casted (in `#with_raw_connection` as + # of Rails 7.2.1). rescue ActiveRecord::StatementInvalid => error - no_db_err_check1 = @connection_parameters && @connection_parameters[:dbname] && error.cause.message.include?(@connection_parameters[:dbname]) - no_db_err_check2 = @connection_parameters && @connection_parameters[:dbname] && error.cause.message.include?("pg_type") - if no_db_err_check1 || no_db_err_check2 - raise ActiveRecord::NoDatabaseError + conn_params = @connection_parameters + if conn_params && conn_params[:dbname] == "postgres" + raise ActiveRecord::ConnectionNotEstablished, error.message + elsif conn_params && conn_params[:dbname] && error.cause.message.include?(conn_params[:dbname]) + raise ActiveRecord::NoDatabaseError.db_error(conn_params[:dbname]) + elsif conn_params && conn_params[:user] && error.cause.message.include?(conn_params[:user]) + raise ActiveRecord::DatabaseConnectionError.username_error(conn_params[:user]) + elsif conn_params && conn_params[:host] && error.cause.message.include?(conn_params[:host]) + raise ActiveRecord::DatabaseConnectionError.hostname_error(conn_params[:host]) else raise ActiveRecord::ConnectionNotEstablished, error.message end diff --git a/test/cases/adapters/postgresql/postgresql_adapter_test.rb b/test/cases/adapters/postgresql/postgresql_adapter_test.rb index 7bf2e7d6..d6165e4d 100644 --- a/test/cases/adapters/postgresql/postgresql_adapter_test.rb +++ b/test/cases/adapters/postgresql/postgresql_adapter_test.rb @@ -25,8 +25,10 @@ def teardown end def test_database_exists_returns_false_when_the_database_does_not_exist - [ { database: "non_extant_database", adapter: "postgresql" }, - { database: "non_extant_database", adapter: "cockroachdb" } ].each do |config| + config_base = ActiveRecord::Base.configurations.configs_for(env_name: "arunit", name: "primary").configuration_hash + [ config_base.merge(database: "non_extant_database", adapter: "cockroachdb"), + config_base.merge(database: "non_extant_database", adapter: "postgresql") + ].each do |config| assert_not ActiveRecord::ConnectionAdapters::CockroachDBAdapter.database_exists?(config), "expected database #{config[:database]} to not exist" end diff --git a/test/cases/helper_cockroachdb.rb b/test/cases/helper_cockroachdb.rb index 654c8520..b33f13e9 100644 --- a/test/cases/helper_cockroachdb.rb +++ b/test/cases/helper_cockroachdb.rb @@ -79,7 +79,7 @@ module TestTimeoutHelper def time_it t0 = Minitest.clock_time - timeout_mins = 5 + timeout_mins = ENV.fetch("TEST_TIMEOUT", 5).to_i Timeout.timeout(timeout_mins * 60, Timeout::Error, "Test took over #{timeout_mins} minutes to finish") do yield end