diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb index 478b4e4729..788cd8e1f0 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb @@ -30,7 +30,11 @@ def mysql2_connection(config) module ConnectionAdapters class Mysql2Adapter < AbstractMysqlAdapter - ER_BAD_DB_ERROR = 1049 + ER_BAD_DB_ERROR = 1049 + ER_ACCESS_DENIED_ERROR = 1045 + ER_CONN_HOST_ERROR = 2003 + ER_UNKOWN_HOST_ERROR = 2005 + ADAPTER_NAME = "Mysql2" include MySQL::DatabaseStatements @@ -40,7 +44,11 @@ def new_client(config) Mysql2::Client.new(config) rescue Mysql2::Error => error if error.error_number == ConnectionAdapters::Mysql2Adapter::ER_BAD_DB_ERROR - raise ActiveRecord::NoDatabaseError + raise ActiveRecord::NoDatabaseError.db_error(config[:database]) + elsif error.error_number == ConnectionAdapters::Mysql2Adapter::ER_ACCESS_DENIED_ERROR + raise ActiveRecord::DatabaseConnectionError.username_error(config[:username]) + elsif [ConnectionAdapters::Mysql2Adapter::ER_CONN_HOST_ERROR, ConnectionAdapters::Mysql2Adapter::ER_UNKOWN_HOST_ERROR].include?(error.error_number) + raise ActiveRecord::DatabaseConnectionError.hostname_error(config[:host]) else raise ActiveRecord::ConnectionNotEstablished, error.message end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 69b8d19ecd..97c7ded525 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -78,7 +78,11 @@ def new_client(conn_params) PG.connect(conn_params) rescue ::PG::Error => error if conn_params && conn_params[:dbname] && error.message.include?(conn_params[:dbname]) - raise ActiveRecord::NoDatabaseError + raise ActiveRecord::NoDatabaseError.db_error(conn_params[:dbname]) + elsif conn_params && conn_params[:user] && error.message.include?(conn_params[:user]) + raise ActiveRecord::DatabaseConnectionError.username_error(conn_params[:user]) + elsif conn_params && conn_params[:hostname] && error.message.include?(conn_params[:hostname]) + raise ActiveRecord::DatabaseConnectionError.hostname_error(conn_params[:hostname]) else raise ActiveRecord::ConnectionNotEstablished, error.message end diff --git a/activerecord/lib/active_record/errors.rb b/activerecord/lib/active_record/errors.rb index 0fe06fbe9d..05c56c0369 100644 --- a/activerecord/lib/active_record/errors.rb +++ b/activerecord/lib/active_record/errors.rb @@ -212,6 +212,52 @@ class PreparedStatementInvalid < ActiveRecordError # Raised when a given database does not exist. class NoDatabaseError < StatementInvalid + include ActiveSupport::ActionableError + + action "Create database" do + ActiveRecord::Tasks::DatabaseTasks.create_current + end + + def initialize(message = nil) + super(message || "Database not found") + end + + class << self + def db_error(db_name) + NoDatabaseError.new(<<~MSG) + We could not find your database: #{db_name}. Which can be found in the database configuration file located at config/database.yml. + + To resolve this issue: + + - Not created a database for this app, or deleted it? You may need to create your database. + - Database name changed? Check your database.yml config has the correct database name. + + To create your database, run:\n\n bin/rails db:create + MSG + end + end + end + + class DatabaseConnectionError < StatementInvalid + def initialize(message = nil) + super(message || "Database connection error") + end + + class << self + def hostname_error(hostname) + DatabaseConnectionError.new(<<~MSG) + We are having an issue connecting with your hostname: #{hostname}.\n + Please check your database configuration or ensure there is a connection open to your hostname. + MSG + end + + def username_error(username) + DatabaseConnectionError.new(<<~MSG) + We are having an issue connecting to your database with your username/password, username: #{username}.\n + Please check your database configuration to ensure the username/password are valid. + MSG + end + end end # Raised when creating a database if it exists.