Skip to content

Commit 275e3ff

Browse files
committed
Make Oj adapter handle JSON::ParseError correctly
1 parent f246bec commit 275e3ff

2 files changed

Lines changed: 28 additions & 9 deletions

File tree

lib/multi_json/adapters/oj.rb

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,25 @@ class Oj < Adapter
88
defaults :load, :mode => :strict, :symbolize_keys => false
99
defaults :dump, :mode => :compat, :time_format => :ruby, :use_to_json => true
1010

11-
ParseError = defined?(::Oj::ParseError) ? ::Oj::ParseError : SyntaxError
11+
# In certain cases OJ gem may throw JSON::ParserError exception instead
12+
# of its own class. Also, we can't expect ::JSON::ParserError and
13+
# ::Oj::ParseError to always be defined, since it's often not the case.
14+
# Because of this, we can't reference those classes directly and have to
15+
# do string comparison instead. This will not catch subclasses, but it
16+
# shouldn't be a problem since the library is not known to be using it
17+
# (at least for now).
18+
class ParseError < ::SyntaxError
19+
WRAPPED_CLASSES = %w[Oj::ParseError JSON::ParserError].to_set.freeze
20+
21+
def self.===(exception)
22+
case exception
23+
when ::SyntaxError
24+
true
25+
else
26+
WRAPPED_CLASSES.include?(exception.class.to_s)
27+
end
28+
end
29+
end
1230

1331
def load(string, options = {})
1432
options[:symbol_keys] = options[:symbolize_keys]

spec/shared/adapter.rb

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,13 @@ def to_json(*)
169169
expect(MultiJson.load('{"abc":"def"}')).to eq('abc' => 'def')
170170
end
171171

172-
it 'raises MultiJson::ParseError on blank input or invalid input' do
173-
[nil, '{"abc"}', ' ', "\t\t\t", "\n", "\x82\xAC\xEF", StringIO.new('')].each do |input|
174-
if input == "\x82\xAC\xEF"
175-
pending 'GSON bug: https://github.com/avsej/gson.rb/issues/3' if adapter.name =~ /Gson/
176-
end
172+
examples = [nil, '{"abc"}', ' ', "\t\t\t", "\n", StringIO.new('')]
173+
#
174+
# GSON bug: https://github.com/avsej/gson.rb/issues/3
175+
examples << "\x82\xAC\xEF" unless adapter.name =~ /Gson/
177176

177+
examples.each do |input|
178+
it "raises MultiJson::ParseError on invalid input: #{input.inspect}" do
178179
expect { MultiJson.load(input) }.to raise_error(MultiJson::ParseError)
179180
end
180181
end
@@ -183,21 +184,21 @@ def to_json(*)
183184
data = '{invalid}'
184185
exception = get_exception(MultiJson::ParseError) { MultiJson.load data }
185186
expect(exception.data).to eq(data)
186-
expect(exception.cause).to be_kind_of(MultiJson.adapter::ParseError)
187+
expect(exception.cause).to match(MultiJson.adapter::ParseError)
187188
end
188189

189190
it 'catches MultiJson::DecodeError for legacy support' do
190191
data = '{invalid}'
191192
exception = get_exception(MultiJson::DecodeError) { MultiJson.load data }
192193
expect(exception.data).to eq(data)
193-
expect(exception.cause).to be_kind_of(MultiJson.adapter::ParseError)
194+
expect(exception.cause).to match(MultiJson.adapter::ParseError)
194195
end
195196

196197
it 'catches MultiJson::LoadError for legacy support' do
197198
data = '{invalid}'
198199
exception = get_exception(MultiJson::LoadError) { MultiJson.load data }
199200
expect(exception.data).to eq(data)
200-
expect(exception.cause).to be_kind_of(MultiJson.adapter::ParseError)
201+
expect(exception.cause).to match(MultiJson.adapter::ParseError)
201202
end
202203

203204
it 'stringifys symbol keys when encoding' do

0 commit comments

Comments
 (0)