Skip to content

Commit

Permalink
Merge pull request #39723 from hahmed/db/friendly-error-when-no-db
Browse files Browse the repository at this point in the history
Create database via UI when ActiveRecord::NoDatabaseError
  • Loading branch information
rafaelfranca authored Aug 6, 2021
2 parents 0c93edd + 1b8ceee commit e2e74cf
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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_UNKNOWN_HOST_ERROR = 2005

ADAPTER_NAME = "Mysql2"

include MySQL::DatabaseStatements
Expand All @@ -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_UNKNOWN_HOST_ERROR].include?(error.error_number)
raise ActiveRecord::DatabaseConnectionError.hostname_error(config[:host])
else
raise ActiveRecord::ConnectionNotEstablished, error.message
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
46 changes: 46 additions & 0 deletions activerecord/lib/active_record/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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:
- Did you create the database for this app, or delete it? You may need to create your database.
- Has the 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)
There is an issue connecting with your hostname: #{hostname}.\n
Please check your database configuration and ensure there is a valid connection to your database.
MSG
end

def username_error(username)
DatabaseConnectionError.new(<<~MSG)
There is 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.
Expand Down

0 comments on commit e2e74cf

Please sign in to comment.