honeybadger 1.12.0.beta3 → 1.13.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.
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