rollbar 1.5.3 → 2.0.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.
@@ -0,0 +1,18 @@
1
+ require 'iconv'
2
+
3
+ module Rollbar
4
+ class LegacyEncoder
5
+ attr_accessor :object
6
+
7
+ def initialize(object)
8
+ @object = object
9
+ end
10
+
11
+ def encode
12
+ value = object.to_s
13
+ encoded_value = ::Iconv.conv('UTF-8//IGNORE', 'UTF-8', value)
14
+
15
+ object.is_a?(Symbol) ? encoded_value.to_sym : encoded_value
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,41 @@
1
+ module Rollbar
2
+ module JSON
3
+ extend self
4
+
5
+ attr_accessor :backend_name
6
+ attr_accessor :dump_method
7
+ attr_accessor :load_method
8
+
9
+ def load_native_json
10
+ require 'json' unless defined?(::JSON)
11
+
12
+ if ::JSON.respond_to?(:dump_default_options)
13
+ options = ::JSON.dump_default_options
14
+ else
15
+ # Default options from json 1.1.9 up to 1.6.1
16
+ options = { :allow_nan => true, :max_nesting => false }
17
+ end
18
+
19
+ self.dump_method = proc { |obj| ::JSON.generate(obj, options) }
20
+ self.load_method = proc { |obj| ::JSON.load(obj) }
21
+ self.backend_name = :json
22
+
23
+ true
24
+ rescue StandardError, ScriptError => err
25
+ Rollbar.log_debug('%p while loading JSON library: %s' % [err, err.message])
26
+ end
27
+
28
+ def dump(object)
29
+ dump_method.call(object)
30
+ end
31
+
32
+ def load(string)
33
+ load_method.call(string)
34
+ end
35
+
36
+ def setup
37
+ load_native_json
38
+ end
39
+ end
40
+ end
41
+
@@ -121,7 +121,7 @@ module Rollbar
121
121
  return {} unless correct_method
122
122
  return {} unless rack_req.env['CONTENT_TYPE'] =~ %r{application/json}i
123
123
 
124
- MultiJson.decode(rack_req.body.read)
124
+ Rollbar::JSON.load(rack_req.body.read)
125
125
  rescue
126
126
  {}
127
127
  ensure
@@ -7,6 +7,8 @@ namespace :rollbar do
7
7
  desc 'Send the deployment notification to Rollbar.'
8
8
  task :deploy do
9
9
  on roles fetch(:rollbar_role) do
10
+ warn("You need to upgrade capistrano to '>= 3.1' version in order to correctly report deploys to Rollbar. (On 3.0, the reported revision will be incorrect.)") if Capistrano::VERSION =~ /^3\.0/
11
+
10
12
  uri = URI.parse 'https://api.rollbar.com/api/1/deploy/'
11
13
  params = {
12
14
  :local_username => fetch(:rollbar_user),
@@ -4,7 +4,7 @@ module Rollbar
4
4
  module Truncation
5
5
  module Mixin
6
6
  def dump(payload)
7
- MultiJson.dump(payload)
7
+ Rollbar::JSON.dump(payload)
8
8
  end
9
9
 
10
10
  def truncate?(result)
@@ -1,3 +1,3 @@
1
1
  module Rollbar
2
- VERSION = "1.5.3"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -16,8 +16,6 @@ Gem::Specification.new do |gem|
16
16
  gem.require_paths = ["lib"]
17
17
  gem.version = Rollbar::VERSION
18
18
 
19
- gem.add_runtime_dependency 'multi_json', '~> 1.3'
20
-
21
19
  gem.add_development_dependency 'rails', '>= 3.0.0'
22
20
  gem.add_development_dependency 'rspec-rails', '>= 2.14.0'
23
21
  gem.add_development_dependency 'database_cleaner', '~> 1.0.0'
@@ -29,4 +27,5 @@ Gem::Specification.new do |gem|
29
27
  gem.add_development_dependency 'resque'
30
28
  gem.add_development_dependency 'delayed_job'
31
29
  gem.add_development_dependency 'rake', '>= 0.9.0'
30
+ gem.add_development_dependency 'redis'
32
31
  end
@@ -43,7 +43,7 @@ describe HomeController do
43
43
  trace = body[:trace] && body[:trace] || body[:trace_chain][0]
44
44
 
45
45
  trace[:exception][:class].should == 'NoMethodError'
46
- trace[:exception][:message].should == 'undefined method `-\' for "1":String'
46
+ trace[:exception][:message].should =~ /^undefined method `-'/
47
47
  end
48
48
  end
49
49
  end
@@ -12,7 +12,7 @@ describe Rollbar::Delay::Resque do
12
12
  end
13
13
 
14
14
  it 'process the payload' do
15
- loaded_hash = MultiJson.load(MultiJson.dump(payload))
15
+ loaded_hash = Rollbar::JSON.load(Rollbar::JSON.dump(payload))
16
16
 
17
17
  expect(Rollbar).to receive(:process_payload_safely).with(loaded_hash)
18
18
  described_class.call(payload)
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ unless RUBY_VERSION.start_with?('1.8')
5
+ require 'rollbar/encoding/encoder'
6
+
7
+ describe Rollbar::Encoding::Encoder do
8
+ subject { described_class.new(object) }
9
+
10
+ shared_examples 'encoding' do
11
+ it 'encodes ir properly' do
12
+ value = subject.encode
13
+
14
+ expect(value).to be_eql(expected)
15
+ end
16
+ end
17
+
18
+ describe '#encode' do
19
+ context 'with ascii chars at end of string' do
20
+ it_behaves_like 'encoding' do
21
+ let(:object) { force_to_ascii("bad value 1\255") }
22
+ let(:expected) { 'bad value 1' }
23
+ end
24
+ end
25
+
26
+ context 'with ascii chars at middle of string' do
27
+ it_behaves_like 'encoding' do
28
+ let(:object) { force_to_ascii("bad\255 value 2") }
29
+ let(:expected) { 'bad value 2' }
30
+ end
31
+ end
32
+
33
+ context 'with ascii chars at end of string' do
34
+ it_behaves_like 'encoding' do
35
+ let(:object) { force_to_ascii("bad value 3\255") }
36
+ let(:expected) { 'bad value 3' }
37
+ end
38
+ end
39
+
40
+ context '0xa0 char in exception object' do
41
+ it_behaves_like 'encoding' do
42
+ let(:object) { "foo \xa0".force_encoding(::Encoding::ISO_8859_1) }
43
+ let(:expected) { "foo " }
44
+ end
45
+ end
46
+
47
+ context 'with bad symbol' do
48
+ it_behaves_like 'encoding' do
49
+ let(:bad_string) { force_to_ascii("inner \x92bad key") }
50
+ let(:object) { bad_string.to_sym }
51
+ let(:expected) { :"inner bad key" }
52
+ end
53
+ end
54
+
55
+ context 'with russian chars in string' do
56
+ it_behaves_like 'encoding' do
57
+ let(:object) { 'Изменение' }
58
+ let(:expected) { 'Изменение' }
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ require 'rollbar/json'
3
+ require 'rollbar/configuration'
4
+
5
+ describe Rollbar::JSON do
6
+ before do
7
+ Rollbar::JSON.setup
8
+ end
9
+
10
+ describe '.dump' do
11
+ it 'has JSON as backend' do
12
+ expect(Rollbar::JSON.backend_name).to be_eql(:json)
13
+ end
14
+
15
+ it 'calls JSON.generate' do
16
+ expect(::JSON).to receive(:generate).once
17
+
18
+ Rollbar::JSON.dump(:foo => :bar)
19
+ end
20
+ end
21
+
22
+ describe '.load' do
23
+ it 'calls MultiJson.load' do
24
+ expect(::JSON).to receive(:load).once
25
+
26
+ Rollbar::JSON.load(:foo => :bar)
27
+ end
28
+ end
29
+ end
@@ -16,7 +16,7 @@ describe Rollbar::Truncation::FramesStrategy do
16
16
  end
17
17
 
18
18
  it 'returns a new payload with 300 frames' do
19
- result = MultiJson.load(described_class.call(payload))
19
+ result = Rollbar::JSON.load(described_class.call(payload))
20
20
 
21
21
  new_frames = result['data']['body']['trace']['frames']
22
22
 
@@ -38,7 +38,7 @@ describe Rollbar::Truncation::FramesStrategy do
38
38
  end
39
39
 
40
40
  it 'returns a new payload with 300 frames for each chain item' do
41
- result = MultiJson.load(described_class.call(payload))
41
+ result = Rollbar::JSON.load(described_class.call(payload))
42
42
 
43
43
  new_frames1 = result['data']['body']['trace_chain'][0]['frames']
44
44
  new_frames2 = result['data']['body']['trace_chain'][1]['frames']
@@ -61,7 +61,7 @@ describe Rollbar::Truncation::FramesStrategy do
61
61
  end
62
62
 
63
63
  it 'returns the original payload' do
64
- result = MultiJson.load(described_class.call(payload))
64
+ result = Rollbar::JSON.load(described_class.call(payload))
65
65
 
66
66
  expect(result).to be_eql(payload)
67
67
  end
@@ -14,7 +14,7 @@ describe Rollbar::Truncation::MinBodyStrategy do
14
14
  end
15
15
 
16
16
  it 'truncates the exception message and frames array' do
17
- result = MultiJson.load(described_class.call(payload))
17
+ result = Rollbar::JSON.load(described_class.call(payload))
18
18
 
19
19
  trace = result['data']['body']['trace']
20
20
  expect(trace['frames']).to have(2).items
@@ -33,7 +33,7 @@ describe Rollbar::Truncation::MinBodyStrategy do
33
33
  end
34
34
 
35
35
  it 'truncates the exception message and frames array' do
36
- result = MultiJson.load(described_class.call(payload))
36
+ result = Rollbar::JSON.load(described_class.call(payload))
37
37
 
38
38
  traces = result['data']['body']['trace_chain']
39
39
  expect(traces[0]['frames']).to have(2).items
@@ -48,7 +48,7 @@ describe Rollbar::Truncation::MinBodyStrategy do
48
48
  let(:payload_fixture) { 'payloads/sample.trace_chain.json' }
49
49
 
50
50
  it "doesn't truncate anything and returns same payload" do
51
- result = MultiJson.load(described_class.call(payload))
51
+ result = Rollbar::JSON.load(described_class.call(payload))
52
52
 
53
53
  expect(result).to be_eql(payload)
54
54
  end
@@ -1,4 +1,4 @@
1
- # encoding: UTF-8
1
+ # encoding: utf-8
2
2
 
3
3
  require 'spec_helper'
4
4
  require 'rollbar/truncation/frames_strategy'
@@ -19,7 +19,7 @@ describe Rollbar::Truncation::StringsStrategy do
19
19
  end
20
20
 
21
21
  it 'should truncate all nested strings in the payload' do
22
- result = MultiJson.load(described_class.call(payload))
22
+ result = Rollbar::JSON.load(described_class.call(payload))
23
23
 
24
24
  expect(result['truncated'].size).to be_eql(1024)
25
25
  expect(result['hash']['inner_truncated'].size).to be_eql(1024)
@@ -36,7 +36,7 @@ describe Rollbar::Truncation::StringsStrategy do
36
36
  end
37
37
 
38
38
  it 'should truncate utf8 strings properly' do
39
- result = MultiJson.load(described_class.call(payload))
39
+ result = Rollbar::JSON.load(described_class.call(payload))
40
40
  expect(result['truncated']).to match(/^Ŝǻмρļẻ śţяịņģa*\.{3}/)
41
41
  end
42
42
  end
@@ -50,7 +50,7 @@ describe Rollbar::Truncation::StringsStrategy do
50
50
  end
51
51
 
52
52
  it 'truncates to 512 size strings' do
53
- result = MultiJson.load(described_class.call(payload))
53
+ result = Rollbar::JSON.load(described_class.call(payload))
54
54
 
55
55
  expect(result['0'].size).to be_eql(512)
56
56
  end
@@ -65,7 +65,7 @@ describe Rollbar::Truncation::StringsStrategy do
65
65
  end
66
66
 
67
67
  it 'truncates to 256 size strings, the third threshold' do
68
- result = MultiJson.load(described_class.call(payload))
68
+ result = Rollbar::JSON.load(described_class.call(payload))
69
69
 
70
70
  expect(result['0'].size).to be_eql(256)
71
71
  end
@@ -80,7 +80,7 @@ describe Rollbar::Truncation::StringsStrategy do
80
80
  end
81
81
 
82
82
  it 'just return the value for third threshold' do
83
- result = MultiJson.load(described_class.call(payload))
83
+ result = Rollbar::JSON.load(described_class.call(payload))
84
84
 
85
85
  expect(result['0'].size).to be_eql(256)
86
86
  end
@@ -202,27 +202,30 @@ describe Rollbar do
202
202
  Rollbar.report_exception(@exception, request_data, person_data)
203
203
  end
204
204
 
205
- it 'should work with an IO object as rack.errors' do
206
- logger_mock.should_receive(:info).with('[Rollbar] Success')
207
-
208
- request_data = {
209
- :params => { :foo => 'bar' },
210
- :url => 'http://localhost/',
211
- :user_ip => '127.0.0.1',
212
- :headers => {},
213
- :GET => { 'baz' => 'boz' },
214
- :session => { :user_id => 123 },
215
- :method => 'GET',
216
- :env => { :'rack.errors' => IO.new(2, File::WRONLY) },
217
- }
218
-
219
- person_data = {
220
- :id => 1,
221
- :username => 'test',
222
- :email => 'test@example.com'
223
- }
224
-
225
- Rollbar.report_exception(@exception, request_data, person_data)
205
+ # Skip jruby 1.9+ (https://github.com/jruby/jruby/issues/2373)
206
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' && (not RUBY_VERSION =~ /^1\.9/)
207
+ it 'should work with an IO object as rack.errors' do
208
+ logger_mock.should_receive(:info).with('[Rollbar] Success')
209
+
210
+ request_data = {
211
+ :params => { :foo => 'bar' },
212
+ :url => 'http://localhost/',
213
+ :user_ip => '127.0.0.1',
214
+ :headers => {},
215
+ :GET => { 'baz' => 'boz' },
216
+ :session => { :user_id => 123 },
217
+ :method => 'GET',
218
+ :env => { :'rack.errors' => IO.new(2, File::WRONLY) },
219
+ }
220
+
221
+ person_data = {
222
+ :id => 1,
223
+ :username => 'test',
224
+ :email => 'test@example.com'
225
+ }
226
+
227
+ Rollbar.report_exception(@exception, request_data, person_data)
228
+ end
226
229
  end
227
230
 
228
231
  it 'should ignore ignored exception classes' do
@@ -4,6 +4,9 @@ require 'logger'
4
4
  require 'socket'
5
5
  require 'spec_helper'
6
6
  require 'girl_friday'
7
+ require 'redis'
8
+ require 'active_support/core_ext/object'
9
+ require 'active_support/json/encoding'
7
10
 
8
11
  begin
9
12
  require 'sucker_punch'
@@ -472,6 +475,23 @@ describe Rollbar do
472
475
  payload['data'][:server][:root].should == '/path/to/root'
473
476
  payload['data'][:server][:branch].should == 'master'
474
477
  end
478
+
479
+ context "with Redis instance in payload and ActiveSupport is enabled" do
480
+ let(:redis) { ::Redis.new }
481
+ let(:payload) do
482
+ {
483
+ :key => {
484
+ :value => redis
485
+ }
486
+ }
487
+ end
488
+ it 'dumps to JSON correctly' do
489
+ redis.set('foo', 'bar')
490
+ json = notifier.send(:dump_payload, payload)
491
+
492
+ expect(json).to be_kind_of(String)
493
+ end
494
+ end
475
495
  end
476
496
 
477
497
  context 'build_payload_body' do
@@ -800,10 +820,13 @@ describe Rollbar do
800
820
  end
801
821
  end
802
822
 
803
- it "should work with an IO object as rack.errors" do
804
- logger_mock.should_receive(:info).with('[Rollbar] Success')
823
+ # Skip jruby 1.9+ (https://github.com/jruby/jruby/issues/2373)
824
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' && (not RUBY_VERSION =~ /^1\.9/)
825
+ it "should work with an IO object as rack.errors" do
826
+ logger_mock.should_receive(:info).with('[Rollbar] Success')
805
827
 
806
- Rollbar.error(exception, :env => { :"rack.errors" => IO.new(2, File::WRONLY) })
828
+ Rollbar.error(exception, :env => { :"rack.errors" => IO.new(2, File::WRONLY) })
829
+ end
807
830
  end
808
831
 
809
832
  it 'should ignore ignored persons' do
@@ -1199,7 +1222,7 @@ describe Rollbar do
1199
1222
  let(:async_handler) do
1200
1223
  proc do |payload|
1201
1224
  # simulate previous gem version
1202
- string_payload = MultiJson.dump(payload)
1225
+ string_payload = Rollbar::JSON.dump(payload)
1203
1226
 
1204
1227
  Rollbar.process_payload(string_payload)
1205
1228
  end
@@ -1361,6 +1384,11 @@ describe Rollbar do
1361
1384
  end
1362
1385
 
1363
1386
  context 'enforce_valid_utf8' do
1387
+ # TODO(jon): all these tests should be removed since they are in
1388
+ # in spec/rollbar/encoding/encoder.rb.
1389
+ #
1390
+ # This should just check that in payload with simple values and
1391
+ # nested values are each one passed through Rollbar::Encoding.encode
1364
1392
  context 'with utf8 string and ruby > 1.8' do
1365
1393
  next unless String.instance_methods.include?(:force_encoding)
1366
1394