Skip to content

Commit

Permalink
Merge pull request #518 from rollbar/improve-large-payload-failsafe
Browse files Browse the repository at this point in the history
Send custom.orig_host and custom.orig_uuid on too large payloads
  • Loading branch information
jondeandres authored Sep 2, 2016
2 parents f7d3788 + c9b8237 commit ffb006f
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 11 deletions.
6 changes: 5 additions & 1 deletion lib/rollbar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ def process_from_async_handler(payload)
end
end

def send_failsafe(message, exception)
def send_failsafe(message, exception, uuid = nil, host = nil)
exception_reason = failsafe_reason(message, exception)

log_error "[Rollbar] Sending failsafe response due to #{exception_reason}"
Expand All @@ -256,6 +256,10 @@ def send_failsafe(message, exception)
:name => 'rollbar-gem',
:version => VERSION
},
:custom => {
:orig_uuid => uuid,
:orig_host => host
},
:internal => true,
:failsafe => true
}
Expand Down
16 changes: 12 additions & 4 deletions lib/rollbar/item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,24 @@ def dump
# from an async handler job, which can be serialized.
stringified_payload = Util::Hash.deep_stringify_keys(payload)
result = Truncation.truncate(stringified_payload)

return result unless Truncation.truncate?(result)

original_size = Rollbar::JSON.dump(payload).bytesize
final_size = result.bytesize
notifier.send_failsafe("Could not send payload due to it being too large after truncating attempts. Original size: #{original_size} Final size: #{final_size}", nil)
logger.error("[Rollbar] Payload too large to be sent: #{Rollbar::JSON.dump(payload)}")
handle_too_large_payload(stringified_payload, result)

nil
end

def handle_too_large_payload(stringified_payload, final_payload)
original_size = Rollbar::JSON.dump(stringified_payload).bytesize
final_size = final_payload.bytesize
uuid = stringified_payload['data']['uuid']
host = stringified_payload['data']['server']['host']

notifier.send_failsafe("Could not send payload due to it being too large after truncating attempts. Original size: #{original_size} Final size: #{final_size}", nil, uuid, host)
logger.error("[Rollbar] Payload too large to be sent for UUID #{uuid}: #{Rollbar::JSON.dump(payload)}")
end

def ignored?
data = payload['data']

Expand Down
3 changes: 2 additions & 1 deletion lib/rollbar/truncation/frames_strategy.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'rollbar/truncation/mixin'
require 'rollbar/util'

module Rollbar
module Truncation
Expand All @@ -10,7 +11,7 @@ def self.call(payload)
end

def call(payload)
new_payload = payload.clone
new_payload = Rollbar::Util.deep_copy(payload)
body = new_payload['data']['body']

if body['trace_chain']
Expand Down
3 changes: 2 additions & 1 deletion lib/rollbar/truncation/min_body_strategy.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'rollbar/truncation/mixin'
require 'rollbar/util'

module Rollbar
module Truncation
Expand All @@ -10,7 +11,7 @@ def self.call(payload)
end

def call(payload)
new_payload = payload.clone
new_payload = Rollbar::Util.deep_copy(payload)
body = new_payload['data']['body']

if body['trace_chain']
Expand Down
2 changes: 1 addition & 1 deletion lib/rollbar/truncation/strings_strategy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def self.call(payload)

def call(payload)
result = nil
new_payload = payload.clone
new_payload = Rollbar::Util.deep_copy(payload)

STRING_THRESHOLDS.each do |threshold|
truncate_proc = truncate_strings_proc(threshold)
Expand Down
12 changes: 10 additions & 2 deletions spec/rollbar/item_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -646,8 +646,16 @@
end

it 'calls Notifier#send_failsafe and logs the error' do
expect(notifier).to receive(:send_failsafe)
expect(logger).to receive(:error)
original_size = Rollbar::JSON.dump(payload).bytesize
final_size = Rollbar::Truncation.truncate(payload.clone).bytesize
# final_size = original_size
rollbar_message = "Could not send payload due to it being too large after truncating attempts. Original size: #{original_size} Final size: #{final_size}"
uuid = payload['data']['uuid']
host = payload['data']['server']['host']
log_message = "[Rollbar] Payload too large to be sent for UUID #{uuid}: #{Rollbar::JSON.dump(payload)}"

expect(notifier).to receive(:send_failsafe).with(rollbar_message, nil, uuid, host)
expect(logger).to receive(:error).with(log_message)

item.dump
end
Expand Down
2 changes: 1 addition & 1 deletion spec/rollbar/truncation/min_body_strategy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
end

context 'with a message payload' do
let(:payload_fixture) { 'payloads/sample.trace_chain.json' }
let(:payload_fixture) { 'payloads/message.json' }

it "doesn't truncate anything and returns same payload" do
result = Rollbar::JSON.load(described_class.call(payload))
Expand Down
12 changes: 12 additions & 0 deletions spec/rollbar_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,18 @@ def backtrace
expect(sent_payload['data'][:body][:message][:body]).to be_eql(expected_body)
end
end

context 'with uuid and host' do
let(:host) { 'the-host' }
let(:uuid) { 'the-uuid' }
it 'sets the uuid and host in correct keys' do
sent_payload = notifier.send(:send_failsafe, 'testing uuid and host',
exception, uuid, host)

expect(sent_payload['data'][:custom][:orig_uuid]).to be_eql('the-uuid')
expect(sent_payload['data'][:custom][:orig_host]).to be_eql('the-host')
end
end
end

context 'when reporting internal error with nil context' do
Expand Down

0 comments on commit ffb006f

Please sign in to comment.