Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
20 changes: 17 additions & 3 deletions lib/bson/decimal128.rb
Original file line number Diff line number Diff line change
Expand Up @@ -305,16 +305,15 @@ def message
end
end

# Raised when the exponent or significand provided is outside the valid range.
#
# @api private
# Raised when the exponent is outside the valid range.
#
# @since 4.2.0
class InvalidRange < RuntimeError

# The custom error message for this error.
#
# @since 4.2.0
# @deprecated
MESSAGE = 'Value out of range for Decimal128 representation.'

# Get the custom error message for the exception.
Expand All @@ -330,6 +329,21 @@ def message
end
end

# Raised when the significand provided is outside the valid range.
#
# @note This class derives from InvalidRange for backwards compatibility,
# however when RUBY-1806 is implemented it should be changed to derive
# from the base BSON exception class.
class UnrepresentablePrecision < InvalidRange

# Get the custom error message for the exception.
#
# @return [ String ] The error message.
def message
'The value contains too much precision for Decimal128 representation'
end
end

Registry.register(BSON_TYPE, self)
end
end
6 changes: 5 additions & 1 deletion lib/bson/decimal128/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,13 @@ def parts_to_bits(significand, exponent, is_negative)
private

def validate_range!(exponent, significand)
unless valid_significand?(significand) && valid_exponent?(exponent)
unless valid_exponent?(exponent)
raise Decimal128::InvalidRange.new
end

unless valid_significand?(significand)
raise Decimal128::UnrepresentablePrecision.new
end
end

def valid_significand?(significand)
Expand Down
16 changes: 16 additions & 0 deletions spec/bson/decimal128_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,22 @@
it_behaves_like 'an initialized BSON::Decimal128'
end
end

context 'when range is exceeded' do
it 'raises InvalidRange' do
lambda do
described_class.new('1e10000')
end.should raise_error(BSON::Decimal128::InvalidRange, /Value out of range/)
end
end

context 'when precision is exceeded' do
it 'raises UnrepresentablePrecision' do
lambda do
described_class.new('1.000000000000000000000000000000000000000000000000001')
end.should raise_error(BSON::Decimal128::UnrepresentablePrecision, /The value contains too much precision/)
end
end
end

context 'when deserializing' do
Expand Down
3 changes: 2 additions & 1 deletion spec/spec_tests/common_driver_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@
let(:valid_errors) do
[
BSON::Decimal128::InvalidString,
BSON::Decimal128::InvalidRange
BSON::Decimal128::InvalidRange,
BSON::Decimal128::UnrepresentablePrecision,
]
end

Expand Down