rollbar 1.5.3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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