honeybadger 1.12.0.beta3 → 1.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/Appraisals +45 -60
  2. data/CHANGELOG.md +3 -28
  3. data/Gemfile.lock +1 -1
  4. data/MIT-LICENSE +1 -2
  5. data/Rakefile +4 -8
  6. data/features/step_definitions/rack_steps.rb +2 -1
  7. data/features/support/env.rb +0 -2
  8. data/gemfiles/rack.gemfile.lock +125 -0
  9. data/gemfiles/rails2.3.gemfile.lock +141 -0
  10. data/gemfiles/rails3.0.gemfile.lock +193 -0
  11. data/gemfiles/rails3.1.gemfile.lock +203 -0
  12. data/gemfiles/rails3.2.gemfile.lock +201 -0
  13. data/gemfiles/rails4.0.gemfile.lock +197 -0
  14. data/gemfiles/rails4.1.gemfile.lock +202 -0
  15. data/gemfiles/rake.gemfile +1 -1
  16. data/gemfiles/rake.gemfile.lock +124 -0
  17. data/gemfiles/sinatra.gemfile.lock +124 -0
  18. data/honeybadger.gemspec +11 -27
  19. data/lib/honeybadger.rb +10 -15
  20. data/lib/honeybadger/configuration.rb +4 -9
  21. data/lib/honeybadger/integrations/sidekiq.rb +9 -17
  22. data/lib/honeybadger/notice.rb +10 -45
  23. data/lib/honeybadger/rack.rb +54 -8
  24. data/lib/honeybadger/rails.rb +4 -5
  25. data/lib/honeybadger/railtie.rb +3 -4
  26. data/lib/honeybadger/user_feedback.rb +67 -3
  27. data/lib/honeybadger/user_informer.rb +21 -3
  28. data/spec/honeybadger/configuration_spec.rb +1 -5
  29. data/spec/honeybadger/notice_spec.rb +1 -126
  30. data/spec/honeybadger/rails_spec.rb +2 -4
  31. metadata +15 -31
  32. data/features/standalone.feature +0 -73
  33. data/features/step_definitions/standalone_steps.rb +0 -12
  34. data/features/step_definitions/thor_steps.rb +0 -4
  35. data/features/support/test.thor +0 -22
  36. data/features/thor.feature +0 -5
  37. data/gemfiles/binding_of_caller.gemfile +0 -8
  38. data/gemfiles/rails.gemfile +0 -11
  39. data/gemfiles/standalone.gemfile +0 -7
  40. data/gemfiles/thor.gemfile +0 -8
  41. data/lib/honeybadger/dependency.rb +0 -65
  42. data/lib/honeybadger/exception_extensions.rb +0 -35
  43. data/lib/honeybadger/integrations.rb +0 -5
  44. data/lib/honeybadger/integrations/delayed_job.rb +0 -20
  45. data/lib/honeybadger/integrations/delayed_job/plugin.rb +0 -31
  46. data/lib/honeybadger/integrations/thor.rb +0 -29
  47. data/lib/honeybadger/payload.rb +0 -29
  48. data/lib/honeybadger/rack/error_notifier.rb +0 -60
  49. data/lib/honeybadger/rack/user_feedback.rb +0 -74
  50. data/lib/honeybadger/rack/user_informer.rb +0 -28
  51. data/spec/honeybadger/dependency_spec.rb +0 -134
  52. data/spec/honeybadger/exception_extensions_spec.rb +0 -40
  53. data/spec/honeybadger/integrations/delayed_job_spec.rb +0 -48
  54. data/spec/honeybadger/integrations/sidekiq_spec.rb +0 -60
  55. data/spec/honeybadger/integrations/thor_spec.rb +0 -29
  56. data/spec/honeybadger/payload_spec.rb +0 -27
@@ -1,74 +0,0 @@
1
- require 'erb'
2
- require 'uri'
3
-
4
- begin
5
- require 'i18n'
6
- rescue LoadError
7
- module Honeybadger
8
- module I18n
9
- def self.t(key, options={})
10
- options[:default]
11
- end
12
- end
13
- end
14
- end
15
-
16
- module Honeybadger
17
- module Rack
18
- class UserFeedback
19
- def initialize(app)
20
- @app = app
21
- end
22
-
23
- def call(env)
24
- status, headers, body = @app.call(env)
25
- if enabled? && env['honeybadger.error_id'] && form = render_form(env['honeybadger.error_id'])
26
- new_body = []
27
- body.each do |chunk|
28
- new_body << chunk.gsub("<!-- HONEYBADGER FEEDBACK -->", form)
29
- end
30
- body.close if body.respond_to?(:close)
31
- headers['Content-Length'] = new_body.reduce(0) { |a,e| a += e.bytesize }.to_s
32
- body = new_body
33
- end
34
- [status, headers, body]
35
- end
36
-
37
- def config
38
- Honeybadger.configuration
39
- end
40
-
41
- def enabled?
42
- config.feedback && config.features['feedback']
43
- end
44
-
45
- def action
46
- URI.parse("#{config.protocol}://#{config.host}:#{config.port}/v1/feedback/").to_s
47
- rescue URI::InvalidURIError
48
- nil
49
- end
50
-
51
- def render_form(error_id, action = action)
52
- return unless action
53
- ERB.new(@template ||= File.read(template_file)).result(binding)
54
- end
55
-
56
- def custom_template_file
57
- @custom_template_file ||= config.project_root &&
58
- File.join(config.project_root, 'lib', 'honeybadger', 'templates', 'feedback_form.erb')
59
- end
60
-
61
- def custom_template_file?
62
- custom_template_file && File.exists?(custom_template_file)
63
- end
64
-
65
- def template_file
66
- if custom_template_file?
67
- custom_template_file
68
- else
69
- File.expand_path('../../templates/feedback_form.erb', __FILE__)
70
- end
71
- end
72
- end
73
- end
74
- end
@@ -1,28 +0,0 @@
1
- module Honeybadger
2
- module Rack
3
- class UserInformer
4
- def initialize(app)
5
- @app = app
6
- end
7
-
8
- def replacement(with)
9
- Honeybadger.configuration.user_information.gsub(/\{\{\s*error_id\s*\}\}/, with.to_s)
10
- end
11
-
12
- def call(env)
13
- status, headers, body = @app.call(env)
14
- if env['honeybadger.error_id'] && Honeybadger.configuration.user_information
15
- new_body = []
16
- replace = replacement(env['honeybadger.error_id'])
17
- body.each do |chunk|
18
- new_body << chunk.gsub("<!-- HONEYBADGER ERROR -->", replace)
19
- end
20
- body.close if body.respond_to?(:close)
21
- headers['Content-Length'] = new_body.reduce(0) { |a,e| a += e.bytesize }.to_s
22
- body = new_body
23
- end
24
- [status, headers, body]
25
- end
26
- end
27
- end
28
- end
@@ -1,134 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Honeybadger::Dependency do
4
- let(:dependency) { Honeybadger::Dependency.new }
5
- subject { dependency }
6
-
7
- before { Honeybadger::Dependency.stub(:instances).and_return([]) }
8
-
9
- describe ".register" do
10
- it "returns a new dependency" do
11
- instance = double()
12
- Honeybadger::Dependency.stub(:new).and_return(instance)
13
- expect(Honeybadger::Dependency.register {}).to eq [instance]
14
- end
15
-
16
- it "registers a new dependency" do
17
- expect { Honeybadger::Dependency.register {} }.to change(described_class, :instances).from([]).to([kind_of(Honeybadger::Dependency)])
18
- end
19
- end
20
-
21
- describe ".inject!" do
22
- it "injects all satisfied instances" do
23
- Honeybadger::Dependency.instances.replace([mock_dependency, mock_dependency])
24
- Honeybadger::Dependency.inject!
25
- end
26
-
27
- it "skips all unsatisfied instances" do
28
- Honeybadger::Dependency.instances.replace([mock_dependency(false), mock_dependency(false)])
29
- Honeybadger::Dependency.inject!
30
- end
31
- end
32
-
33
- describe "#requirement" do
34
- let(:block) { Proc.new {} }
35
-
36
- it "returns and Array of requirements" do
37
- expect(subject.requirement(&block)).to eq [block]
38
- end
39
-
40
- it "registers a new requirement" do
41
- expect { subject.requirement(&block) }.to change(subject, :requirements).from([]).to([block])
42
- end
43
- end
44
-
45
- describe "#injection" do
46
- let(:block) { Proc.new {} }
47
-
48
- it "returns an Array of injections" do
49
- expect(subject.injection(&block)).to eq [block]
50
- end
51
-
52
- it "registers a new injection" do
53
- expect { subject.injection(&block) }.to change(subject, :injections).from([]).to([block])
54
- end
55
- end
56
-
57
- describe "#ok?" do
58
- subject { dependency.ok? }
59
-
60
- context "when not injected yet" do
61
- it { should be_true }
62
- end
63
-
64
- context "when already injected" do
65
- before { dependency.inject! }
66
-
67
- it { should be_false }
68
- end
69
-
70
- context "all requirements are met" do
71
- before do
72
- 3.times { dependency.requirement { true } }
73
- end
74
- end
75
-
76
- context "some requirements fail" do
77
- before do
78
- 3.times { dependency.requirement { true } }
79
- dependency.requirement { false }
80
- end
81
-
82
- it { should be_false }
83
- end
84
-
85
- context "some requirements error" do
86
- before do
87
- dependency.requirement { true }
88
- dependency.requirement { fail 'oops!' }
89
- end
90
-
91
- it { should be_false }
92
-
93
- it "logs the failure" do
94
- Honeybadger.should_receive(:write_verbose_log).with(/oops!/, :error).once
95
- dependency.ok?
96
- end
97
- end
98
- end
99
-
100
- describe "#inject!" do
101
- it "calls injections" do
102
- dependency.injections.replace([mock_injection, mock_injection])
103
- dependency.inject!
104
- end
105
-
106
- context "some injections fail" do
107
- before do
108
- failing_injection = Proc.new { fail 'oh noes!' }
109
- dependency.injections.replace([mock_injection, failing_injection, mock_injection(false)])
110
- end
111
-
112
- it "halts injection silently" do
113
- expect { dependency.inject! }.not_to raise_error
114
- end
115
-
116
- it "logs the failure" do
117
- Honeybadger.should_receive(:write_verbose_log).with(/oh noes!/, :error).once
118
- dependency.inject!
119
- end
120
-
121
- it "marks the dependency as injected" do
122
- expect { dependency.inject!}.to change(dependency, :injected?).from(false).to(true)
123
- end
124
- end
125
- end
126
-
127
- def mock_dependency(ok = true)
128
- double(:ok? => ok).tap { |d| d.send(ok ? :should_receive : :should_not_receive, :inject!) }
129
- end
130
-
131
- def mock_injection(positive = true)
132
- double().tap { |d| d.send(positive ? :should_receive : :should_not_receive, :call) }
133
- end
134
- end
@@ -1,40 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Exception, :unless => defined?(BindingOfCaller) do
4
- should { respond_to :__honeybadger_bindings_stack }
5
- its(:__honeybadger_bindings_stack) { should eq([]) }
6
- end
7
-
8
- describe Exception, :if => defined?(BindingOfCaller) do
9
- describe "#set_backtrace" do
10
- context "call stack does not match current file" do
11
- it "changes the bindings stack" do
12
- expect { subject.set_backtrace(['foo.rb:1']) }.to change(subject, :__honeybadger_bindings_stack).from([])
13
- end
14
- end
15
-
16
- context "call stack includes current file" do
17
- before do
18
- subject.stub(:caller).and_return(["#{File.expand_path('../../../lib/honeybadger/exception_extensions.rb', __FILE__)}:1"])
19
- end
20
-
21
- it "does not change the bindings stack" do
22
- expect { subject.set_backtrace(['foo.rb:1']) }.not_to change(subject, :__honeybadger_bindings_stack).from([])
23
- end
24
- end
25
-
26
- context "call stack includes a non-matching line" do
27
- before do
28
- subject.stub(:caller).and_return(['(foo)'])
29
- end
30
-
31
- it "skips the non-matching line" do
32
- expect { subject.set_backtrace(['foo.rb:1']) }.not_to raise_error
33
- end
34
-
35
- it "changes the bindings stack" do
36
- expect { subject.set_backtrace(['foo.rb:1']) }.to change(subject, :__honeybadger_bindings_stack).from([])
37
- end
38
- end
39
- end
40
- end
@@ -1,48 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "DelayedJob Dependency" do
4
- before do
5
- Honeybadger::Dependency.reset!
6
- end
7
-
8
- context "when delayed_job is not installed" do
9
- it "fails quietly" do
10
- expect { Honeybadger::Dependency.inject! }.not_to raise_error
11
- end
12
- end
13
-
14
- context "when delayed_job is installed" do
15
- let(:plugins_array) { [] }
16
- let(:plugin_class) do
17
- Class.new do
18
- def self.callbacks(&block)
19
- end
20
- end
21
- end
22
-
23
- before do
24
- Object.const_set(:Delayed, Module.new)
25
- ::Delayed.const_set(:Plugins, Module.new)
26
- ::Delayed::Plugins.const_set(:Plugin, plugin_class)
27
- ::Delayed.const_set(:Worker, double(:plugins => plugins_array))
28
- end
29
-
30
- after { Object.send(:remove_const, :Delayed) }
31
-
32
- it "adds the plugin to DelayedJob" do
33
- Honeybadger::Dependency.inject!
34
- expect(plugins_array).to include(Honeybadger::Integrations::DelayedJob::Plugin)
35
- end
36
-
37
- context "and delayed_job_honeybadger is installed" do
38
- before do
39
- ::Delayed::Plugins.const_set(:Honeybadger, Class.new(plugin_class))
40
- end
41
-
42
- it "warns the user of the conflict" do
43
- Honeybadger.should_receive(:write_verbose_log).with(/Support for Delayed Job has been moved/, :warn).once
44
- Honeybadger::Dependency.inject!
45
- end
46
- end
47
- end
48
- end
@@ -1,60 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Sidekiq Dependency" do
4
- before do
5
- Honeybadger::Dependency.reset!
6
- end
7
-
8
- context "when sidekiq is not installed" do
9
- it "fails quietly" do
10
- expect { Honeybadger::Dependency.inject! }.not_to raise_error
11
- end
12
- end
13
-
14
- context "when sidekiq is installed" do
15
- let(:shim) do
16
- Class.new do
17
- def self.configure_server
18
- end
19
- end
20
- end
21
-
22
- let(:config) { double('config', :error_handlers => []) }
23
- let(:chain) { double('chain', :add => true) }
24
-
25
- before do
26
- Object.const_set(:Sidekiq, shim)
27
- ::Sidekiq.stub(:configure_server).and_yield(config)
28
- config.stub(:server_middleware).and_yield(chain)
29
- end
30
-
31
- after { Object.send(:remove_const, :Sidekiq) }
32
-
33
- context "when version is less than 3" do
34
- before do
35
- ::Sidekiq.const_set(:VERSION, '2.17.7')
36
- end
37
-
38
- it "adds the server middleware" do
39
- chain.should_receive(:add).with(Honeybadger::Integrations::Sidekiq::Middleware)
40
- Honeybadger::Dependency.inject!
41
- end
42
-
43
- it "doesn't add the error handler" do
44
- Honeybadger::Dependency.inject!
45
- expect(config.error_handlers).to be_empty
46
- end
47
- end
48
-
49
- context "when version is 3 or greater" do
50
- before do
51
- ::Sidekiq.const_set(:VERSION, '3.0.0')
52
- end
53
-
54
- it "adds the error handler" do
55
- Honeybadger::Dependency.inject!
56
- expect(config.error_handlers).not_to be_empty
57
- end
58
- end
59
- end
60
- end
@@ -1,29 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Thor Dependency" do
4
- before do
5
- Honeybadger::Dependency.reset!
6
- end
7
-
8
- context "when thor is not installed" do
9
- it "fails quietly" do
10
- expect { Honeybadger::Dependency.inject! }.not_to raise_error
11
- end
12
- end
13
-
14
- context "when thor is installed" do
15
- let(:shim) do
16
- double('fake thor')
17
- end
18
-
19
- before do
20
- Object.const_set(:Thor, shim)
21
- end
22
- after { Object.send(:remove_const, :Thor) }
23
-
24
- it "includes integration module into Thor" do
25
- shim.should_receive(:send).with(:include, Honeybadger::Integrations::Thor)
26
- Honeybadger::Dependency.inject!
27
- end
28
- end
29
- end
@@ -1,27 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Honeybadger::Payload do
4
- its(:max_depth) { should eq 20 }
5
-
6
- context "when max_depth option is passed to #initialize" do
7
- subject { described_class.new({}, :max_depth => 5) }
8
- its(:max_depth) { should eq 5 }
9
-
10
- context "when initialized with a bad object" do
11
- it "raises ArgumentError" do
12
- expect { described_class.new([], :max_depth => 5) }.to raise_error(ArgumentError)
13
- end
14
- end
15
- end
16
-
17
- describe "#sanitize" do
18
- let(:deep_hash) { {}.tap {|h| 30.times.each {|i| h = h[i.to_s] = {:string => 'string'} }} }
19
- let(:expected_hash) { {}.tap {|h| max_depth.times.each {|i| h = h[i.to_s] = {:string => 'string'} }} }
20
- let(:sanitized_hash) { described_class.new(deep_hash, :max_depth => max_depth) }
21
- let(:max_depth) { 10 }
22
-
23
- it "truncates nested hashes to max_depth" do
24
- expect(sanitized_hash).to eq(expected_hash)
25
- end
26
- end
27
- end