aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/errors.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/errors.rb')
-rw-r--r--activerecord/lib/active_record/errors.rb59
1 files changed, 42 insertions, 17 deletions
diff --git a/activerecord/lib/active_record/errors.rb b/activerecord/lib/active_record/errors.rb
index f61bc7b9e8..20cc987d6e 100644
--- a/activerecord/lib/active_record/errors.rb
+++ b/activerecord/lib/active_record/errors.rb
@@ -38,6 +38,10 @@ module ActiveRecord
class AdapterNotSpecified < ActiveRecordError
end
+ # Raised when a model makes a query but it has not specified an associated table.
+ class TableNotSpecified < ActiveRecordError
+ end
+
# Raised when Active Record cannot find database adapter specified in
# +config/database.yml+ or programmatically.
class AdapterNotFound < ActiveRecordError
@@ -49,6 +53,10 @@ module ActiveRecord
class ConnectionNotEstablished < ActiveRecordError
end
+ # Raised when a write to the database is attempted on a read only connection.
+ class ReadOnlyError < ActiveRecordError
+ end
+
# Raised when Active Record cannot find a record by given id or set of ids.
class RecordNotFound < ActiveRecordError
attr_reader :model, :primary_key, :id
@@ -64,7 +72,7 @@ module ActiveRecord
# Raised by {ActiveRecord::Base#save!}[rdoc-ref:Persistence#save!] and
# {ActiveRecord::Base.create!}[rdoc-ref:Persistence::ClassMethods#create!]
- # methods when a record is invalid and can not be saved.
+ # methods when a record is invalid and cannot be saved.
class RecordNotSaved < ActiveRecordError
attr_reader :record
@@ -97,9 +105,13 @@ module ActiveRecord
#
# Wraps the underlying database error as +cause+.
class StatementInvalid < ActiveRecordError
- def initialize(message = nil)
+ def initialize(message = nil, sql: nil, binds: nil)
super(message || $!.try(:message))
+ @sql = sql
+ @binds = binds
end
+
+ attr_reader :sql, :binds
end
# Defunct wrapper class kept for compatibility.
@@ -118,16 +130,26 @@ module ActiveRecord
# Raised when a foreign key constraint cannot be added because the column type does not match the referenced column type.
class MismatchedForeignKey < StatementInvalid
- def initialize(adapter = nil, message: nil, table: nil, foreign_key: nil, target_table: nil, primary_key: nil)
- @adapter = adapter
+ def initialize(
+ message: nil,
+ sql: nil,
+ binds: nil,
+ table: nil,
+ foreign_key: nil,
+ target_table: nil,
+ primary_key: nil,
+ primary_key_column: nil
+ )
if table
- msg = +<<~EOM
- Column `#{foreign_key}` on table `#{table}` has a type of `#{column_type(table, foreign_key)}`.
- This does not match column `#{primary_key}` on `#{target_table}`, which has type `#{column_type(target_table, primary_key)}`.
- To resolve this issue, change the type of the `#{foreign_key}` column on `#{table}` to be :integer. (For example `t.integer #{foreign_key}`).
+ type = primary_key_column.bigint? ? :bigint : primary_key_column.type
+ msg = <<~EOM.squish
+ Column `#{foreign_key}` on table `#{table}` does not match column `#{primary_key}` on `#{target_table}`,
+ which has type `#{primary_key_column.sql_type}`.
+ To resolve this issue, change the type of the `#{foreign_key}` column on `#{table}` to be :#{type}.
+ (For example `t.#{type} :#{foreign_key}`).
EOM
else
- msg = +<<~EOM
+ msg = <<~EOM.squish
There is a mismatch between the foreign key and primary key column types.
Verify that the foreign key column type and the primary key of the associated table match types.
EOM
@@ -135,13 +157,8 @@ module ActiveRecord
if message
msg << "\nOriginal message: #{message}"
end
- super(msg)
+ super(msg, sql: sql, binds: binds)
end
-
- private
- def column_type(table, column)
- @adapter.columns(table).detect { |c| c.name == column }.sql_type
- end
end
# Raised when a record cannot be inserted or updated because it would violate a not null constraint.
@@ -336,16 +353,24 @@ module ActiveRecord
class IrreversibleOrderError < ActiveRecordError
end
+ # Superclass for errors that have been aborted (either by client or server).
+ class QueryAborted < StatementInvalid
+ end
+
# LockWaitTimeout will be raised when lock wait timeout exceeded.
class LockWaitTimeout < StatementInvalid
end
# StatementTimeout will be raised when statement timeout exceeded.
- class StatementTimeout < StatementInvalid
+ class StatementTimeout < QueryAborted
end
# QueryCanceled will be raised when canceling statement due to user request.
- class QueryCanceled < StatementInvalid
+ class QueryCanceled < QueryAborted
+ end
+
+ # AdapterTimeout will be raised when database clients times out while waiting from the server.
+ class AdapterTimeout < QueryAborted
end
# UnknownAttributeReference is raised when an unknown and potentially unsafe