Skip to content

Commit

Permalink
truncator: fix circular references
Browse files Browse the repository at this point in the history
Fixes #285 (Error in stackframe json)
  • Loading branch information
kyrylo committed Nov 29, 2017
1 parent d23d2e9 commit daca8eb
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
10 changes: 9 additions & 1 deletion lib/airbrake-ruby/truncator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@ class Truncator
# strings with +ENCODING_OPTIONS+
TEMP_ENCODING = 'utf-16'.freeze

# @return [String] what to append when something is a circular reference
CIRCULAR = '[Circular]'.freeze

# @return [String] what to append when something is truncated
TRUNCATED = '[Truncated]'.freeze

# @return [Array<Class>] The types that can contain references to itself
CIRCULAR_TYPES = [Array, Hash, Set].freeze

# @param [Integer] max_size maximum size of hashes, arrays and strings
def initialize(max_size)
@max_size = max_size
Expand All @@ -28,7 +33,10 @@ def initialize(max_size)
# @param [Set] seen The cache that helps to detect recursion
# @return [Object] truncated object
def truncate(object, seen = Set.new)
return CIRCULAR if seen.include?(object)
if seen.include?(object)
return CIRCULAR if CIRCULAR_TYPES.any? { |t| object.is_a?(t) }
return object
end
truncate_object(object, seen << object)
end

Expand Down
23 changes: 23 additions & 0 deletions spec/truncator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -211,5 +211,28 @@ def obj.to_json
expect(subject).to be_frozen
end
end

context "given an array with hashes and hash-like objects with identical keys" do
let(:hashie) { Class.new(Hash) }

let(:object) do
{
errors: [
{ file: 'a' },
hashie.new.merge(file: 'bcde')
]
}
end

it "truncates values" do
expect(subject).to eq(
errors: [
{ file: 'a' },
hashie.new.merge(file: 'bcd[Truncated]')
]
)
expect(subject).to be_frozen
end
end
end
end

0 comments on commit daca8eb

Please sign in to comment.