rollbar 2.1.2 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 553381499b916556da8272eadf551847254ffcaa
4
- data.tar.gz: c80b393ccaa1cb9e2c2d46646703510852965ecf
3
+ metadata.gz: 245d598a698d57310a524065495b585450e183d8
4
+ data.tar.gz: ae4841097d594e0b58528806f3b151163e9b432a
5
5
  SHA512:
6
- metadata.gz: d31b2d8d6d71c30c5888c3dacd631cda2f584d2de6a8b4cb238ca8c484a7037745904cfa5925ea5eca5e2100a93afa8c56681deab6292ffeefd97d4a764b078d
7
- data.tar.gz: eedb32f0cc342297fbb7c48f989b8568bb6856ee385bc8f5d65c7d95334f58ed0a3121511d5824c870ddb1545e94fe8f2c265435a1afeb458730f2a2d927d581
6
+ metadata.gz: 43011a9710f91e3640dc5542d099b112ea4b2424842d2db8045a5f14444027ec225b15380539d7f38ecde2258744db6e74df31855b1a293c36d106c7ee2ac0dd
7
+ data.tar.gz: 47bfe86f356e5efa27fea9ef15c5150541d4c065c9d8c72f0def6c1ad2813d8ff0be5bc1381b0b9bea38f7df49f3fc3dfb03a3b23a362510da196a1391596668
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Change Log
2
2
 
3
+ ## 2.2.0
4
+
5
+ New features:
6
+
7
+ - Raise internal exceptions when processing reports from async handlers, instead of swallowing them. This allows queue systems (e.g. Sidekiq, Resque) to track and retry errored jobs. See [#282](https://github.com/rollbar/rollbar-gem/pull/282)
8
+ - Send the error class name when reporting internal errors. See [#283](https://github.com/rollbar/rollbar-gem/pull/283)
9
+
3
10
  ## 2.1.2
4
11
 
5
12
  Bug fix:
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Rollbar notifier for Ruby [![Build Status](https://api.travis-ci.org/rollbar/rollbar-gem.svg?branch=v2.1.2)](https://travis-ci.org/rollbar/rollbar-gem/branches)
1
+ # Rollbar notifier for Ruby [![Build Status](https://api.travis-ci.org/rollbar/rollbar-gem.svg?branch=v2.2.0)](https://travis-ci.org/rollbar/rollbar-gem/branches)
2
2
 
3
3
  <!-- RemoveNext -->
4
4
  [Rollbar](https://rollbar.com) is an error tracking service for Ruby and other languages. The Rollbar service will alert you of problems with your code and help you understand them in a ways never possible before. We love it and we hope you will too.
@@ -12,7 +12,7 @@ This is the Ruby library for Rollbar. It will instrument many kinds of Ruby appl
12
12
  Add this line to your application's Gemfile:
13
13
 
14
14
  ```ruby
15
- gem 'rollbar', '~> 2.1.2'
15
+ gem 'rollbar', '~> 2.2.0'
16
16
  ```
17
17
 
18
18
  And then execute:
@@ -518,11 +518,11 @@ You can supply your own handler using ```config.async_handler```. The object to
518
518
  ```ruby
519
519
  config.use_async = true
520
520
  config.async_handler = Proc.new { |payload|
521
- Thread.new { Rollbar.process_payload_safely(payload) }
521
+ Thread.new { Rollbar.process_from_async_handler(payload) }
522
522
  }
523
523
  ```
524
524
 
525
- Make sure you pass ```payload``` to ```Rollbar.process_payload_safely``` in your own implementation.
525
+ Make sure you pass ```payload``` to ```Rollbar.process_from_async_handler``` in your own implementation.
526
526
 
527
527
  ## Failover handlers
528
528
 
@@ -666,19 +666,6 @@ You can find upgrading notes in [UPGRADING.md](UPGRADING.md).
666
666
 
667
667
  ## Known Issues
668
668
 
669
- We've received some issues from users having problems when they use [Oj](https://github.com/ohler55/oj) as the JSON serialization library with [MultiJson](https://github.com/intridea/multi_json). To avoid these problems, we recommend upgrading to Oj version 2.11.0:
670
-
671
- ```ruby
672
- gem 'oj', '~> 2.11.0'
673
- ```
674
-
675
- If you are using Oj but cannot upgrade, you can work around this with:
676
-
677
- ```ruby
678
- require 'json'
679
- MultiJson.use(:json_common)
680
- ```
681
-
682
669
  If you are using jRuby with Oracle and JDK7, you may be expecting some errors sending reports to our API. This is caused by a bug in that JDK and the primer number used in the SSL algorithm. In order to fix this you can set the next configuration:
683
670
 
684
671
  ```ruby
@@ -47,7 +47,7 @@ Rollbar.configure do |config|
47
47
  # config.use_async = true
48
48
  # Supply your own async handler:
49
49
  # config.async_handler = Proc.new { |payload|
50
- # Thread.new { Rollbar.process_payload_safely(payload) }
50
+ # Thread.new { Rollbar.process_from_async_handler(payload) }
51
51
  # }
52
52
 
53
53
  # Enable asynchronous reporting (using sucker_punch)
data/lib/rollbar.rb CHANGED
@@ -17,7 +17,7 @@ require 'rollbar/logger_proxy'
17
17
  require 'rollbar/exception_reporter'
18
18
  require 'rollbar/util'
19
19
  require 'rollbar/railtie' if defined?(Rails::VERSION)
20
- require 'rollbar/delay/girl_friday'
20
+ require 'rollbar/delay/girl_friday' if defined?(GirlFriday)
21
21
  require 'rollbar/delay/thread'
22
22
  require 'rollbar/truncation'
23
23
 
@@ -27,7 +27,7 @@ module Rollbar
27
27
  Rack::Multipart::UploadedFile
28
28
  ].freeze
29
29
  PUBLIC_NOTIFIER_METHODS = %w(debug info warn warning error critical log logger
30
- process_payload process_payload_safely scope send_failsafe log_info log_debug
30
+ process_payload process_from_async_handler scope send_failsafe log_info log_debug
31
31
  log_warning log_error silenced)
32
32
 
33
33
  class Notifier
@@ -195,10 +195,39 @@ module Rollbar
195
195
  raise e
196
196
  end
197
197
 
198
- def process_payload_safely(payload)
199
- process_payload(payload)
200
- rescue => e
201
- report_internal_error(e)
198
+ # We will reraise exceptions in this method so async queues
199
+ # can retry the job or, in general, handle an error report some way.
200
+ #
201
+ # At same time that exception is silenced so we don't generate
202
+ # infinite reports. This example is what we want to avoid:
203
+ #
204
+ # 1. New exception in a the project is raised
205
+ # 2. That report enqueued to Sidekiq queue.
206
+ # 3. The Sidekiq job tries to send the report to our API
207
+ # 4. The report fails, for example cause a network failure,
208
+ # and a exception is raised
209
+ # 5. We report an internal error for that exception
210
+ # 6. We reraise the exception so Sidekiq job fails and
211
+ # Sidekiq can retry the job reporting the original exception
212
+ # 7. Because the job failed and Sidekiq can be managed by rollbar we'll
213
+ # report a new exception.
214
+ # 8. Go to point 2.
215
+ #
216
+ # We'll then push to Sidekiq queue indefinitely until the network failure
217
+ # is fixed.
218
+ #
219
+ # Using Rollbar.silenced we avoid the above behavior but Sidekiq
220
+ # will have a chance to retry the original job.
221
+ def process_from_async_handler(payload)
222
+ Rollbar.silenced do
223
+ begin
224
+ process_payload(payload)
225
+ rescue => e
226
+ report_internal_error(e)
227
+
228
+ raise
229
+ end
230
+ end
202
231
  end
203
232
 
204
233
  def custom_data
@@ -544,23 +573,28 @@ module Rollbar
544
573
  end
545
574
 
546
575
  def send_failsafe(message, exception)
576
+ body = 'Failsafe from rollbar-gem: '
547
577
  log_error "[Rollbar] Sending failsafe response due to #{message}."
578
+
548
579
  if exception
549
580
  begin
581
+ body += "#{exception.class.name}: #{message}"
550
582
  log_error "[Rollbar] #{exception.class.name}: #{exception}"
551
- rescue => e
583
+ rescue
584
+ end
585
+ else
586
+ begin
587
+ body += message.to_s
588
+ rescue
552
589
  end
553
590
  end
554
591
 
555
- config = configuration
556
- environment = config.environment
557
-
558
592
  failsafe_data = {
559
593
  :level => 'error',
560
- :environment => environment.to_s,
594
+ :environment => configuration.environment.to_s,
561
595
  :body => {
562
596
  :message => {
563
- :body => "Failsafe from rollbar-gem: #{message}"
597
+ :body => body
564
598
  }
565
599
  },
566
600
  :notifier => {
@@ -581,6 +615,8 @@ module Rollbar
581
615
  rescue => e
582
616
  log_error "[Rollbar] Error sending failsafe : #{e}"
583
617
  end
618
+
619
+ failsafe_payload
584
620
  end
585
621
 
586
622
  def schedule_payload(payload)
@@ -3,22 +3,28 @@ module Rollbar
3
3
  class GirlFriday
4
4
 
5
5
  class << self
6
- attr_accessor :queue
6
+ def queue_class
7
+ ::GirlFriday::WorkQueue
8
+ end
7
9
 
8
10
  def call(payload)
9
11
  new.call(payload)
10
12
  end
11
- end
12
13
 
13
- def queue_class
14
- ::GirlFriday::WorkQueue
14
+ def queue
15
+ @queue ||= self.queue_class.new(nil, :size => 5) do |payload|
16
+ begin
17
+ Rollbar.process_from_async_handler(payload)
18
+ rescue
19
+ # According to https://github.com/mperham/girl_friday/wiki#error-handling
20
+ # we reraise the exception so it can be handled some way
21
+ raise
22
+ end
23
+ end
24
+ end
15
25
  end
16
26
 
17
27
  def call(payload)
18
- self.class.queue = queue_class.new(nil, :size => 5) do |payload|
19
- Rollbar.process_payload_safely(payload)
20
- end
21
-
22
28
  self.class.queue.push(payload)
23
29
  end
24
30
  end
@@ -23,7 +23,12 @@ module Rollbar
23
23
  end
24
24
 
25
25
  def perform(payload)
26
- Rollbar.process_payload_safely(payload)
26
+ begin
27
+ Rollbar.process_from_async_handler(payload)
28
+ rescue
29
+ # Raise the exception so Resque can track the errored job
30
+ raise
31
+ end
27
32
  end
28
33
  end
29
34
  end
@@ -16,7 +16,13 @@ module Rollbar
16
16
  include ::Sidekiq::Worker
17
17
 
18
18
  def perform(*args)
19
- Rollbar.process_payload_safely(*args)
19
+ begin
20
+ Rollbar.process_from_async_handler(*args)
21
+ rescue
22
+ # Raise the exception so Sidekiq can track the errored job
23
+ # and retry it
24
+ raise
25
+ end
20
26
  end
21
27
  end
22
28
  end
@@ -11,7 +11,20 @@ module Rollbar
11
11
  end
12
12
 
13
13
  def perform(*args)
14
- Rollbar.process_payload_safely(*args)
14
+ begin
15
+ Rollbar.process_from_async_handler(*args)
16
+ rescue
17
+ # SuckerPunch can configure an exception handler with:
18
+ #
19
+ # SuckerPunch.exception_handler { # do something here }
20
+ #
21
+ # This is just passed to Celluloid.exception_handler which will
22
+ # push the reiceved block to an array of handlers, by default empty, [].
23
+ #
24
+ # We reraise the exception here casue it's safe and users could have defined
25
+ # their own exception handler for SuckerPunch
26
+ raise
27
+ end
15
28
  end
16
29
  end
17
30
  end
@@ -6,7 +6,18 @@ module Rollbar
6
6
  end
7
7
 
8
8
  def call(payload)
9
- ::Thread.new { Rollbar.process_payload_safely(payload) }
9
+ ::Thread.new do
10
+ begin
11
+ Rollbar.process_from_async_handler(payload)
12
+ rescue
13
+ # Here we swallow the exception:
14
+ # 1. The original report wasn't sent.
15
+ # 2. An internal error was sent and logged
16
+ #
17
+ # If users want to handle this in some way they
18
+ # can provide a more custom Thread based implementation
19
+ end
20
+ end
10
21
  end
11
22
  end
12
23
  end
@@ -1,3 +1,3 @@
1
1
  module Rollbar
2
- VERSION = "2.1.2"
2
+ VERSION = "2.2.0"
3
3
  end
data/rollbar.gemspec CHANGED
@@ -4,7 +4,7 @@ require File.expand_path('../lib/rollbar/version', __FILE__)
4
4
  Gem::Specification.new do |gem|
5
5
  gem.authors = ["Rollbar, Inc."]
6
6
  gem.email = ["support@rollbar.com"]
7
- gem.description = %q{Rails plugin to catch and send exceptions to Rollbar}
7
+ gem.description = %q{Easy and powerful exception tracking for Ruby}
8
8
  gem.executables = ['rollbar-rails-runner']
9
9
  gem.summary = %q{Reports exceptions to Rollbar}
10
10
  gem.homepage = "https://rollbar.com"
@@ -17,7 +17,7 @@ describe Rollbar::Delay::Sidekiq, :if => RUBY_VERSION != '1.8.7' do
17
17
 
18
18
  describe "#perform" do
19
19
  it "performs payload" do
20
- Rollbar.should_receive(:process_payload_safely).with(payload)
20
+ Rollbar.should_receive(:process_from_async_handler).with(payload)
21
21
  subject.perform payload
22
22
  end
23
23
  end
@@ -26,7 +26,7 @@ describe Rollbar::Delay::Sidekiq, :if => RUBY_VERSION != '1.8.7' do
26
26
  shared_examples "a Rollbar processor" do
27
27
 
28
28
  it "processes payload" do
29
- Rollbar.should_receive(:process_payload_safely).with(payload)
29
+ Rollbar.should_receive(:process_from_async_handler).with(payload)
30
30
 
31
31
  subject.call payload
32
32
  described_class.drain
@@ -17,7 +17,7 @@ describe Rollbar::Delay::SuckerPunch, :if => RUBY_VERSION != '1.8.7' do
17
17
  let(:payload) { "anything" }
18
18
 
19
19
  it "performs the task asynchronously" do
20
- Rollbar.should_receive(:process_payload_safely)
20
+ Rollbar.should_receive(:process_from_async_handler)
21
21
 
22
22
  Rollbar::Delay::SuckerPunch.call payload
23
23
  end
@@ -6,14 +6,36 @@ require 'girl_friday'
6
6
  require 'rollbar/delay/girl_friday'
7
7
 
8
8
  describe Rollbar::Delay::GirlFriday do
9
+ before do
10
+ queue_class = ::GirlFriday::WorkQueue.immediate!
11
+ allow(::Rollbar::Delay::GirlFriday).to receive(:queue_class).and_return(queue_class)
12
+ end
13
+
9
14
  describe '.call' do
10
15
  let(:payload) do
11
16
  { :key => 'value' }
12
17
  end
13
18
 
14
19
  it 'push the payload into the queue' do
15
- expect_any_instance_of(::GirlFriday::WorkQueue).to receive(:push).with(payload)
20
+ expect(Rollbar).to receive(:process_from_async_handler).with(payload)
21
+
16
22
  described_class.call(payload)
17
23
  end
24
+
25
+ context 'with exceptions processing payload' do
26
+ let(:exception) { Exception.new }
27
+
28
+ before do
29
+ expect(Rollbar).to receive(:process_from_async_handler).with(payload).and_raise(exception)
30
+ end
31
+
32
+ it 'raises an exception cause we are using immediate queue' do
33
+ # This will not happen with a norma work queue cause this:
34
+ # https://github.com/mperham/girl_friday/blob/master/lib/girl_friday/work_queue.rb#L90-L106
35
+ expect do
36
+ described_class.call(payload)
37
+ end.to raise_error(exception)
38
+ end
39
+ end
18
40
  end
19
41
  end
@@ -7,15 +7,31 @@ describe Rollbar::Delay::Resque do
7
7
  { :key => 'value' }
8
8
  end
9
9
 
10
+ let(:loaded_hash) do
11
+ Rollbar::JSON.load(Rollbar::JSON.dump(payload))
12
+ end
13
+
10
14
  before do
11
15
  allow(Resque).to receive(:inline?).and_return(true)
12
16
  end
13
17
 
14
18
  it 'process the payload' do
15
- loaded_hash = Rollbar::JSON.load(Rollbar::JSON.dump(payload))
16
-
17
- expect(Rollbar).to receive(:process_payload_safely).with(loaded_hash)
19
+ expect(Rollbar).to receive(:process_from_async_handler).with(loaded_hash)
18
20
  described_class.call(payload)
19
21
  end
22
+
23
+ context 'with exceptions processing payload' do
24
+ let(:exception) { Exception.new }
25
+
26
+ before do
27
+ expect(Rollbar).to receive(:process_from_async_handler).with(loaded_hash).and_raise(exception)
28
+ end
29
+
30
+ it 'raises an exception' do
31
+ expect do
32
+ described_class.call(payload)
33
+ end.to raise_error(exception)
34
+ end
35
+ end
20
36
  end
21
37
  end
@@ -5,10 +5,23 @@ describe Rollbar::Delay::Thread do
5
5
  let(:payload) { { :key => 'value' } }
6
6
 
7
7
  it 'process the payload in a new thread' do
8
- expect(Rollbar).to receive(:process_payload_safely).with(payload)
8
+ expect(Rollbar).to receive(:process_from_async_handler).with(payload)
9
9
 
10
- th = described_class.call(payload)
11
- th.join
10
+ described_class.call(payload).join
11
+ end
12
+
13
+ context 'with exceptions processing payload' do
14
+ let(:exception) { StandardError.new }
15
+
16
+ before do
17
+ expect(Rollbar).to receive(:process_from_async_handler).with(payload).and_raise(exception)
18
+ end
19
+
20
+ it 'doesnt raise any exception' do
21
+ expect do
22
+ described_class.call(payload).join
23
+ end.not_to raise_error(exception)
24
+ end
12
25
  end
13
26
  end
14
27
  end
data/spec/rollbar_spec.rb CHANGED
@@ -1562,17 +1562,27 @@ describe Rollbar do
1562
1562
  end
1563
1563
 
1564
1564
  context "send_failsafe" do
1565
+ let(:exception) { StandardError.new }
1566
+
1565
1567
  it "should not crash when given a message and exception" do
1566
- begin
1567
- 1 / 0
1568
- rescue => e
1569
- notifier.send(:send_failsafe, "test failsafe", e)
1570
- end
1568
+ sent_payload = notifier.send(:send_failsafe, "test failsafe", exception)
1569
+
1570
+ expected_message = 'Failsafe from rollbar-gem: StandardError: test failsafe'
1571
+ expect(sent_payload['data'][:body][:message][:body]).to be_eql(expected_message)
1571
1572
  end
1572
1573
 
1573
1574
  it "should not crash when given all nils" do
1574
1575
  notifier.send(:send_failsafe, nil, nil)
1575
1576
  end
1577
+
1578
+ context 'without exception object' do
1579
+ it 'just sends the given message' do
1580
+ sent_payload = notifier.send(:send_failsafe, "test failsafe", nil)
1581
+
1582
+ expected_message = 'Failsafe from rollbar-gem: test failsafe'
1583
+ expect(sent_payload['data'][:body][:message][:body]).to be_eql(expected_message)
1584
+ end
1585
+ end
1576
1586
  end
1577
1587
 
1578
1588
  context 'when reporting internal error with nil context' do
@@ -1704,15 +1714,20 @@ describe Rollbar do
1704
1714
  end
1705
1715
  end
1706
1716
 
1707
- describe '.process_payload_safely' do
1717
+ describe '.process_from_async_handler' do
1708
1718
  context 'with errors' do
1709
1719
  let(:exception) { StandardError.new('the error') }
1710
1720
 
1711
- it 'doesnt raise anything and sends internal error' do
1721
+ it 'raises anything and sends internal error' do
1712
1722
  allow(Rollbar.notifier).to receive(:process_payload).and_raise(exception)
1713
1723
  expect(Rollbar.notifier).to receive(:report_internal_error).with(exception)
1714
1724
 
1715
- Rollbar.notifier.process_payload_safely({})
1725
+ expect do
1726
+ Rollbar.notifier.process_from_async_handler({})
1727
+ end.to raise_error(exception)
1728
+
1729
+ rollbar_do_not_report = exception.instance_variable_get(:@_rollbar_do_not_report)
1730
+ expect(rollbar_do_not_report).to be_eql(true)
1716
1731
  end
1717
1732
  end
1718
1733
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rollbar
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rollbar, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-14 00:00:00.000000000 Z
11
+ date: 2015-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -178,7 +178,7 @@ dependencies:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
- description: Rails plugin to catch and send exceptions to Rollbar
181
+ description: Easy and powerful exception tracking for Ruby
182
182
  email:
183
183
  - support@rollbar.com
184
184
  executables: