Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create database via UI when ActiveRecord::NoDatabaseError #39723

Merged
merged 2 commits into from
Aug 6, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add a more detailed error messages for connection issues to pg and
mysql. Allow database to be create via a button on the UI for some
connection issues.
  • Loading branch information
hahmed committed May 17, 2021
commit b28711ffa015217e2c24c87152a2f37d8aca1c83
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_UNKOWN_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_UNKOWN_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
hahmed marked this conversation as resolved.
Show resolved Hide resolved
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.
hahmed marked this conversation as resolved.
Show resolved Hide resolved
- Database name changed? Check your database.yml config has the correct database name.
hahmed marked this conversation as resolved.
Show resolved Hide resolved

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
hahmed marked this conversation as resolved.
Show resolved Hide resolved
Please check your database configuration or ensure there is a connection open to your hostname.
hahmed marked this conversation as resolved.
Show resolved Hide resolved
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
hahmed marked this conversation as resolved.
Show resolved Hide resolved
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