Translate numeric value out of range to the specific exception
Raise `ActiveRecord::RangeError` when values that executed are out of range.
This commit is contained in:
parent
cf6c2948d5
commit
49edce37f9
@ -738,6 +738,7 @@ def add_options_for_index_columns(quoted_columns, **options)
|
||||
ER_DO_NOT_HAVE_DEFAULT = 1364
|
||||
ER_NO_REFERENCED_ROW_2 = 1452
|
||||
ER_DATA_TOO_LONG = 1406
|
||||
ER_OUT_OF_RANGE = 1264
|
||||
ER_LOCK_DEADLOCK = 1213
|
||||
ER_CANNOT_ADD_FOREIGN = 1215
|
||||
ER_CANNOT_CREATE_TABLE = 1005
|
||||
@ -758,6 +759,8 @@ def translate_exception(exception, message)
|
||||
end
|
||||
when ER_DATA_TOO_LONG
|
||||
ValueTooLong.new(message)
|
||||
when ER_OUT_OF_RANGE
|
||||
RangeError.new(message)
|
||||
when ER_NOT_NULL_VIOLATION, ER_DO_NOT_HAVE_DEFAULT
|
||||
NotNullViolation.new(message)
|
||||
when ER_LOCK_DEADLOCK
|
||||
|
@ -408,6 +408,7 @@ def postgresql_version
|
||||
|
||||
# See http://www.postgresql.org/docs/current/static/errcodes-appendix.html
|
||||
VALUE_LIMIT_VIOLATION = "22001"
|
||||
NUMERIC_VALUE_OUT_OF_RANGE = "22003"
|
||||
NOT_NULL_VIOLATION = "23502"
|
||||
FOREIGN_KEY_VIOLATION = "23503"
|
||||
UNIQUE_VIOLATION = "23505"
|
||||
@ -424,6 +425,8 @@ def translate_exception(exception, message)
|
||||
InvalidForeignKey.new(message)
|
||||
when VALUE_LIMIT_VIOLATION
|
||||
ValueTooLong.new(message)
|
||||
when NUMERIC_VALUE_OUT_OF_RANGE
|
||||
RangeError.new(message)
|
||||
when NOT_NULL_VIOLATION
|
||||
NotNullViolation.new(message)
|
||||
when SERIALIZATION_FAILURE
|
||||
|
@ -194,7 +194,7 @@ def find(*ids) # :nodoc:
|
||||
name, primary_key, id)
|
||||
end
|
||||
record
|
||||
rescue RangeError
|
||||
rescue ::RangeError
|
||||
raise RecordNotFound.new("Couldn't find #{name} with an out of range value for '#{primary_key}'",
|
||||
name, primary_key)
|
||||
end
|
||||
@ -223,7 +223,7 @@ def find_by(*args) # :nodoc:
|
||||
statement.execute(hash.values, self, connection).first
|
||||
rescue TypeError
|
||||
raise ActiveRecord::StatementInvalid
|
||||
rescue RangeError
|
||||
rescue ::RangeError
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
@ -159,6 +159,10 @@ class NotNullViolation < StatementInvalid
|
||||
class ValueTooLong < StatementInvalid
|
||||
end
|
||||
|
||||
# Raised when values that executed are out of range.
|
||||
class RangeError < StatementInvalid
|
||||
end
|
||||
|
||||
# Raised when number of bind variables in statement given to +:condition+ key
|
||||
# (for example, when using {ActiveRecord::Base.find}[rdoc-ref:FinderMethods#find] method)
|
||||
# does not match number of expected values supplied.
|
||||
|
@ -76,7 +76,7 @@ def find(*args)
|
||||
# Post.find_by "published_at < ?", 2.weeks.ago
|
||||
def find_by(arg, *args)
|
||||
where(arg, *args).take
|
||||
rescue RangeError
|
||||
rescue ::RangeError
|
||||
nil
|
||||
end
|
||||
|
||||
@ -84,7 +84,7 @@ def find_by(arg, *args)
|
||||
# an ActiveRecord::RecordNotFound error.
|
||||
def find_by!(arg, *args)
|
||||
where(arg, *args).take!
|
||||
rescue RangeError
|
||||
rescue ::RangeError
|
||||
raise RecordNotFound.new("Couldn't find #{@klass.name} with an out of range value",
|
||||
@klass.name)
|
||||
end
|
||||
@ -333,7 +333,7 @@ def exists?(conditions = :none)
|
||||
end
|
||||
|
||||
connection.select_value(relation, "#{name} Exists", relation.bound_attributes) ? true : false
|
||||
rescue RangeError
|
||||
rescue ::RangeError
|
||||
false
|
||||
end
|
||||
|
||||
@ -458,7 +458,7 @@ def find_with_ids(*ids)
|
||||
else
|
||||
find_some(ids)
|
||||
end
|
||||
rescue RangeError
|
||||
rescue ::RangeError
|
||||
raise RecordNotFound, "Couldn't find #{@klass.name} with an out of range ID"
|
||||
end
|
||||
|
||||
|
@ -226,6 +226,14 @@ def test_value_limit_violations_are_translated_to_specific_exception
|
||||
|
||||
assert_not_nil error.cause
|
||||
end
|
||||
|
||||
def test_numeric_value_out_of_ranges_are_translated_to_specific_exception
|
||||
error = assert_raises(ActiveRecord::RangeError) do
|
||||
Book.connection.create("INSERT INTO books(author_id) VALUES (2147483648)")
|
||||
end
|
||||
|
||||
assert_not_nil error.cause
|
||||
end
|
||||
end
|
||||
|
||||
def test_disable_referential_integrity
|
||||
|
@ -34,10 +34,10 @@ class UnsignedType < ActiveRecord::Base
|
||||
assert_raise(ActiveModel::RangeError) do
|
||||
UnsignedType.create(unsigned_bigint: -10)
|
||||
end
|
||||
assert_raise(ActiveRecord::StatementInvalid) do
|
||||
assert_raise(ActiveRecord::RangeError) do
|
||||
UnsignedType.create(unsigned_float: -10.0)
|
||||
end
|
||||
assert_raise(ActiveRecord::StatementInvalid) do
|
||||
assert_raise(ActiveRecord::RangeError) do
|
||||
UnsignedType.create(unsigned_decimal: -10.0)
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user