diff --git a/lib/raygun.rb b/lib/raygun.rb index 0c21fc8..ec85912 100644 --- a/lib/raygun.rb +++ b/lib/raygun.rb @@ -6,11 +6,6 @@ require "rack" require "ostruct" -begin - require "pry" -rescue LoadError -end - require "raygun/version" require "raygun/configuration" require "raygun/client" @@ -152,6 +147,8 @@ def track_exception_sync(exception_instance, env, user, retry_count) env[:custom_data] ||= {} env[:custom_data].merge!(original_stacktrace: exception_instance.backtrace) + ::Raygun::Breadcrumbs::Store.clear + track_exception(new_exception, env, user, retry_count - 1) else raise e diff --git a/lib/raygun/breadcrumbs/breadcrumb.rb b/lib/raygun/breadcrumbs/breadcrumb.rb index 8395805..06f1ad8 100644 --- a/lib/raygun/breadcrumbs/breadcrumb.rb +++ b/lib/raygun/breadcrumbs/breadcrumb.rb @@ -25,6 +25,10 @@ def build_payload v != nil end] end + + def size + return message.length + 100 + end end end end diff --git a/lib/raygun/breadcrumbs/store.rb b/lib/raygun/breadcrumbs/store.rb index 3f1381d..505cd2f 100644 --- a/lib/raygun/breadcrumbs/store.rb +++ b/lib/raygun/breadcrumbs/store.rb @@ -47,6 +47,16 @@ def self.any? stored != nil && stored.length > 0 end + def self.take_until_size(size) + breadcrumb_size = 0 + + stored.reverse.take_while do |crumb| + breadcrumb_size += crumb.size + + breadcrumb_size < size + end.reverse + end + private def self.should_record?(crumb) diff --git a/lib/raygun/client.rb b/lib/raygun/client.rb index 24a023a..3c09b4a 100644 --- a/lib/raygun/client.rb +++ b/lib/raygun/client.rb @@ -5,6 +5,7 @@ class Client ENV_IP_ADDRESS_KEYS = %w(action_dispatch.remote_ip raygun.remote_ip REMOTE_ADDR) NO_API_KEY_MESSAGE = "[RAYGUN] Just a note, you've got no API Key configured, which means we can't report exceptions. Specify your Raygun API key using Raygun#setup (find yours at https://app.raygun.io)" + MAX_BREADCRUMBS_SIZE = 100_000 include HTTParty @@ -214,7 +215,7 @@ def build_payload_hash(exception_instance, env = {}, user = nil) } } store = ::Raygun::Breadcrumbs::Store - error_details[:breadcrumbs] = store.stored.map(&:build_payload) if store.any? + error_details[:breadcrumbs] = store.take_until_size(MAX_BREADCRUMBS_SIZE).map(&:build_payload) if store.any? Raygun.log('set details and breadcrumbs') diff --git a/raygun4ruby.gemspec b/raygun4ruby.gemspec index 66b173b..9f8f16d 100644 --- a/raygun4ruby.gemspec +++ b/raygun4ruby.gemspec @@ -37,7 +37,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency "webmock" spec.add_development_dependency 'rails', "= 5.2" - spec.add_development_dependency 'sqlite3' + spec.add_development_dependency 'sqlite3', '~> 1.3.6' spec.add_development_dependency 'capybara' spec.add_development_dependency "rspec-rails" spec.add_development_dependency "launchy" diff --git a/spec/raygun/breadcrumbs/breadcrumb_spec.rb b/spec/raygun/breadcrumbs/breadcrumb_spec.rb index 67861b0..3f517aa 100644 --- a/spec/raygun/breadcrumbs/breadcrumb_spec.rb +++ b/spec/raygun/breadcrumbs/breadcrumb_spec.rb @@ -129,6 +129,43 @@ module Breadcrumbs expect(payload[:CustomData]).to eq(foo: 'bar') end end + + describe "#size" do + before do + Timecop.freeze + Store.initialize + end + after do + Timecop.return + Store.clear + end + + let(:message) { "This is a breadcrumb message" } + + let(:breadcrumb) do + Store.record( + message: message, + category: "test", + level: :info, + class_name: "HomeController", + method_name: "index", + line_number: 17, + metadata: { + foo: 'bar' + } + ) + + Store.stored[0] + end + + let(:size) { breadcrumb.size } + + it "returns the estimated size of the breadcrumb" do + # Can't check all the fields but message so assume a standard 100 length for all of them + # The message should be the bulk of large breadcrumbs anyway + expect(size).to eq(message.length + 100) + end + end end end end diff --git a/spec/raygun/breadcrumbs/store_spec.rb b/spec/raygun/breadcrumbs/store_spec.rb index 7a9ce77..d3d457b 100644 --- a/spec/raygun/breadcrumbs/store_spec.rb +++ b/spec/raygun/breadcrumbs/store_spec.rb @@ -67,6 +67,30 @@ module Breadcrumbs end end + describe "#take_until_size" do + before do + subject.initialize + end + + it "takes the most recent breadcrumbs until the size limit is reached" do + subject.record(message: '1' * 100) + subject.record(message: '2' * 100) + subject.record(message: '3' * 100) + + crumbs = subject.take_until_size(500) + + expect(crumbs.length).to eq(2) + expect(crumbs[0].message).to eq('2' * 100) + expect(crumbs[1].message).to eq('3' * 100) + end + + it "does not crash with no recorded breadcrumbs" do + crumbs = subject.take_until_size(500) + + expect(crumbs).to eq([]) + end + end + context "adding a breadcrumb" do class Foo include ::Raygun::Breadcrumbs