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.
- data/Appraisals +45 -60
- data/CHANGELOG.md +3 -28
- data/Gemfile.lock +1 -1
- data/MIT-LICENSE +1 -2
- data/Rakefile +4 -8
- data/features/step_definitions/rack_steps.rb +2 -1
- data/features/support/env.rb +0 -2
- data/gemfiles/rack.gemfile.lock +125 -0
- data/gemfiles/rails2.3.gemfile.lock +141 -0
- data/gemfiles/rails3.0.gemfile.lock +193 -0
- data/gemfiles/rails3.1.gemfile.lock +203 -0
- data/gemfiles/rails3.2.gemfile.lock +201 -0
- data/gemfiles/rails4.0.gemfile.lock +197 -0
- data/gemfiles/rails4.1.gemfile.lock +202 -0
- data/gemfiles/rake.gemfile +1 -1
- data/gemfiles/rake.gemfile.lock +124 -0
- data/gemfiles/sinatra.gemfile.lock +124 -0
- data/honeybadger.gemspec +11 -27
- data/lib/honeybadger.rb +10 -15
- data/lib/honeybadger/configuration.rb +4 -9
- data/lib/honeybadger/integrations/sidekiq.rb +9 -17
- data/lib/honeybadger/notice.rb +10 -45
- data/lib/honeybadger/rack.rb +54 -8
- data/lib/honeybadger/rails.rb +4 -5
- data/lib/honeybadger/railtie.rb +3 -4
- data/lib/honeybadger/user_feedback.rb +67 -3
- data/lib/honeybadger/user_informer.rb +21 -3
- data/spec/honeybadger/configuration_spec.rb +1 -5
- data/spec/honeybadger/notice_spec.rb +1 -126
- data/spec/honeybadger/rails_spec.rb +2 -4
- metadata +15 -31
- data/features/standalone.feature +0 -73
- data/features/step_definitions/standalone_steps.rb +0 -12
- data/features/step_definitions/thor_steps.rb +0 -4
- data/features/support/test.thor +0 -22
- data/features/thor.feature +0 -5
- data/gemfiles/binding_of_caller.gemfile +0 -8
- data/gemfiles/rails.gemfile +0 -11
- data/gemfiles/standalone.gemfile +0 -7
- data/gemfiles/thor.gemfile +0 -8
- data/lib/honeybadger/dependency.rb +0 -65
- data/lib/honeybadger/exception_extensions.rb +0 -35
- data/lib/honeybadger/integrations.rb +0 -5
- data/lib/honeybadger/integrations/delayed_job.rb +0 -20
- data/lib/honeybadger/integrations/delayed_job/plugin.rb +0 -31
- data/lib/honeybadger/integrations/thor.rb +0 -29
- data/lib/honeybadger/payload.rb +0 -29
- data/lib/honeybadger/rack/error_notifier.rb +0 -60
- data/lib/honeybadger/rack/user_feedback.rb +0 -74
- data/lib/honeybadger/rack/user_informer.rb +0 -28
- data/spec/honeybadger/dependency_spec.rb +0 -134
- data/spec/honeybadger/exception_extensions_spec.rb +0 -40
- data/spec/honeybadger/integrations/delayed_job_spec.rb +0 -48
- data/spec/honeybadger/integrations/sidekiq_spec.rb +0 -60
- data/spec/honeybadger/integrations/thor_spec.rb +0 -29
- 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
|