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.
- 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
data/features/standalone.feature
DELETED
@@ -1,73 +0,0 @@
|
|
1
|
-
Feature: Use the notifier in a plain Ruby app
|
2
|
-
Scenario: Rescue and exception in a Rack app
|
3
|
-
Given the following Ruby app:
|
4
|
-
"""
|
5
|
-
require 'honeybadger'
|
6
|
-
|
7
|
-
Honeybadger.configure do |config|
|
8
|
-
config.api_key = 'my_api_key'
|
9
|
-
config.logger = Logger.new STDOUT
|
10
|
-
end
|
11
|
-
|
12
|
-
begin
|
13
|
-
fail 'oops!'
|
14
|
-
rescue => e
|
15
|
-
Honeybadger.notify(e)
|
16
|
-
end
|
17
|
-
"""
|
18
|
-
When I execute the file
|
19
|
-
Then I should receive a Honeybadger notification
|
20
|
-
|
21
|
-
Scenario: Dependency injection
|
22
|
-
Given the following Ruby app:
|
23
|
-
"""
|
24
|
-
require 'honeybadger/dependency'
|
25
|
-
|
26
|
-
Honeybadger::Dependency.register do
|
27
|
-
injection { puts 'injected' }
|
28
|
-
end
|
29
|
-
|
30
|
-
require 'honeybadger'
|
31
|
-
|
32
|
-
Honeybadger.configure do |config|
|
33
|
-
config.api_key = 'my_api_key'
|
34
|
-
config.logger = Logger.new STDOUT
|
35
|
-
end
|
36
|
-
|
37
|
-
begin
|
38
|
-
fail 'oops!'
|
39
|
-
rescue => e
|
40
|
-
Honeybadger.notify(e)
|
41
|
-
end
|
42
|
-
"""
|
43
|
-
When I execute the file
|
44
|
-
Then the output should contain "injected"
|
45
|
-
And I should receive a Honeybadger notification
|
46
|
-
|
47
|
-
# TODO: also test 'Then the output should contain "injection failure"' after default
|
48
|
-
# logging is added.
|
49
|
-
Scenario: Dependency injection exception
|
50
|
-
Given the following Ruby app:
|
51
|
-
"""
|
52
|
-
require 'honeybadger/dependency'
|
53
|
-
|
54
|
-
Honeybadger::Dependency.register do
|
55
|
-
injection { fail 'injection failure' }
|
56
|
-
end
|
57
|
-
|
58
|
-
require 'honeybadger'
|
59
|
-
|
60
|
-
Honeybadger.configure do |config|
|
61
|
-
config.api_key = 'my_api_key'
|
62
|
-
config.logger = Logger.new STDOUT
|
63
|
-
end
|
64
|
-
|
65
|
-
begin
|
66
|
-
fail 'oops!'
|
67
|
-
rescue => e
|
68
|
-
Honeybadger.notify(e)
|
69
|
-
end
|
70
|
-
"""
|
71
|
-
When I execute the file
|
72
|
-
Then the output should not contain "injected"
|
73
|
-
And I should receive a Honeybadger notification
|
@@ -1,12 +0,0 @@
|
|
1
|
-
Given /^the following Ruby app:$/ do |definition|
|
2
|
-
File.open(RUBY_FILE, 'w') do |file|
|
3
|
-
file.puts "require 'rubygems'"
|
4
|
-
file.write(IO.read(SHIM_FILE))
|
5
|
-
file.write(definition)
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
When /^I execute the file$/ do
|
10
|
-
step %(I run `ruby #{RUBY_FILE}`)
|
11
|
-
end
|
12
|
-
|
data/features/support/test.thor
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'thor'
|
2
|
-
require 'honeybadger'
|
3
|
-
|
4
|
-
require 'sham_rack'
|
5
|
-
|
6
|
-
ShamRack.at("api.honeybadger.io", 443).stub.tap do |app|
|
7
|
-
app.register_resource("/v1/notices/", %({"id":"123456789"}), "application/json")
|
8
|
-
app.register_resource("/v1/ping/", %({"features":{"notices":true,"feedback":true}, "limit":null}), "application/json")
|
9
|
-
end
|
10
|
-
|
11
|
-
Honeybadger.configure do |config|
|
12
|
-
config.api_key = 'asdf'
|
13
|
-
config.debug = true
|
14
|
-
config.logger = Logger.new(STDOUT)
|
15
|
-
end
|
16
|
-
|
17
|
-
class Test < Thor
|
18
|
-
desc "honeybadger", "this goes boom"
|
19
|
-
def honeybadger
|
20
|
-
fail 'boom'
|
21
|
-
end
|
22
|
-
end
|
data/features/thor.feature
DELETED
data/gemfiles/rails.gemfile
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "rails", "~> 4.0.3"
|
6
|
-
gem "honeybadger", :path=>"../"
|
7
|
-
gem "capistrano", "~> 3.0"
|
8
|
-
gem "better_errors", :require=>false
|
9
|
-
gem "rack-mini-profiler", :require=>false
|
10
|
-
|
11
|
-
gemspec :path=>"../"
|
data/gemfiles/standalone.gemfile
DELETED
data/gemfiles/thor.gemfile
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
module Honeybadger
|
2
|
-
class Dependency
|
3
|
-
class << self
|
4
|
-
@@instances = []
|
5
|
-
|
6
|
-
def instances
|
7
|
-
@@instances
|
8
|
-
end
|
9
|
-
|
10
|
-
def register
|
11
|
-
instances << new.tap { |d| d.instance_eval(&Proc.new) }
|
12
|
-
end
|
13
|
-
|
14
|
-
def inject!
|
15
|
-
instances.each do |dependency|
|
16
|
-
dependency.inject! if dependency.ok?
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def reset!
|
21
|
-
instances.each(&:reset!)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def initialize
|
26
|
-
@injected = false
|
27
|
-
@requirements = []
|
28
|
-
@injections = []
|
29
|
-
end
|
30
|
-
|
31
|
-
def requirement
|
32
|
-
@requirements << Proc.new
|
33
|
-
end
|
34
|
-
|
35
|
-
def injection
|
36
|
-
@injections << Proc.new
|
37
|
-
end
|
38
|
-
|
39
|
-
def ok?
|
40
|
-
!@injected && @requirements.all?(&:call)
|
41
|
-
rescue => e
|
42
|
-
Honeybadger.write_verbose_log("Exception caught while verifying dependency: #{e.class} -- #{e.message}", :error)
|
43
|
-
false
|
44
|
-
end
|
45
|
-
|
46
|
-
def inject!
|
47
|
-
@injections.each(&:call)
|
48
|
-
rescue => e
|
49
|
-
Honeybadger.write_verbose_log("Exception caught while injecting dependency: #{e.class} -- #{e.message}", :error)
|
50
|
-
false
|
51
|
-
ensure
|
52
|
-
@injected = true
|
53
|
-
end
|
54
|
-
|
55
|
-
def reset!
|
56
|
-
@injected = false
|
57
|
-
end
|
58
|
-
|
59
|
-
def injected?
|
60
|
-
@injected
|
61
|
-
end
|
62
|
-
|
63
|
-
attr_reader :requirements, :injections
|
64
|
-
end
|
65
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module Honeybadger
|
2
|
-
module ExceptionExtensions
|
3
|
-
module Bindings
|
4
|
-
def self.included(base)
|
5
|
-
base.send(:alias_method, :set_backtrace_without_honeybadger, :set_backtrace)
|
6
|
-
base.send(:alias_method, :set_backtrace, :set_backtrace_with_honeybadger)
|
7
|
-
end
|
8
|
-
|
9
|
-
def set_backtrace_with_honeybadger(*args, &block)
|
10
|
-
if caller.none? { |loc| loc.match(Honeybadger::Backtrace::Line::INPUT_FORMAT) && Regexp.last_match(1) == __FILE__ }
|
11
|
-
@__honeybadger_bindings_stack = binding.callers.drop(1)
|
12
|
-
end
|
13
|
-
|
14
|
-
set_backtrace_without_honeybadger(*args, &block)
|
15
|
-
end
|
16
|
-
|
17
|
-
def __honeybadger_bindings_stack
|
18
|
-
@__honeybadger_bindings_stack || []
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
module NullBindings
|
23
|
-
def __honeybadger_bindings_stack
|
24
|
-
[]
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
begin
|
31
|
-
require 'binding_of_caller'
|
32
|
-
Exception.send(:include, Honeybadger::ExceptionExtensions::Bindings)
|
33
|
-
rescue LoadError
|
34
|
-
Exception.send(:include, Honeybadger::ExceptionExtensions::NullBindings)
|
35
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module Honeybadger
|
2
|
-
Dependency.register do
|
3
|
-
requirement { defined?(::Delayed::Plugins::Plugin) }
|
4
|
-
requirement { defined?(::Delayed::Worker.plugins) }
|
5
|
-
requirement do
|
6
|
-
if delayed_job_honeybadger = defined?(::Delayed::Plugins::Honeybadger)
|
7
|
-
Honeybadger.write_verbose_log("Support for Delayed Job has been moved " \
|
8
|
-
"to the honeybadger gem. Please remove " \
|
9
|
-
"delayed_job_honeybadger from your " \
|
10
|
-
"Gemfile.", :warn)
|
11
|
-
end
|
12
|
-
!delayed_job_honeybadger
|
13
|
-
end
|
14
|
-
|
15
|
-
injection do
|
16
|
-
require 'honeybadger/integrations/delayed_job/plugin'
|
17
|
-
::Delayed::Worker.plugins << Integrations::DelayedJob::Plugin
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module Honeybadger
|
2
|
-
module Integrations
|
3
|
-
module DelayedJob
|
4
|
-
class Plugin < ::Delayed::Plugins::Plugin
|
5
|
-
callbacks do |lifecycle|
|
6
|
-
lifecycle.around(:invoke_job) do |job, *args, &block|
|
7
|
-
begin
|
8
|
-
block.call(job, *args)
|
9
|
-
rescue Exception => error
|
10
|
-
::Honeybadger.notify_or_ignore(
|
11
|
-
:error_class => error.class.name,
|
12
|
-
:error_message => "#{ error.class.name }: #{ error.message }",
|
13
|
-
:backtrace => error.backtrace,
|
14
|
-
:context => {
|
15
|
-
:job_id => job.id,
|
16
|
-
:handler => job.handler,
|
17
|
-
:last_error => job.last_error,
|
18
|
-
:attempts => job.attempts,
|
19
|
-
:queue => job.queue
|
20
|
-
}
|
21
|
-
)
|
22
|
-
raise error
|
23
|
-
ensure
|
24
|
-
::Honeybadger.context.clear!
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module Honeybadger
|
2
|
-
module Integrations
|
3
|
-
module Thor
|
4
|
-
def self.included(base)
|
5
|
-
base.class_eval do
|
6
|
-
no_commands do
|
7
|
-
alias_method :invoke_command_without_honeybadger, :invoke_command
|
8
|
-
alias_method :invoke_command, :invoke_command_with_honeybadger
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def invoke_command_with_honeybadger(*args)
|
14
|
-
invoke_command_without_honeybadger(*args)
|
15
|
-
rescue Exception => e
|
16
|
-
Honeybadger.notify_or_ignore(e)
|
17
|
-
raise
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
Dependency.register do
|
23
|
-
requirement { defined?(::Thor) }
|
24
|
-
|
25
|
-
injection do
|
26
|
-
Thor.send(:include, Integrations::Thor)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
data/lib/honeybadger/payload.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
require 'delegate'
|
2
|
-
|
3
|
-
module Honeybadger
|
4
|
-
class Payload < SimpleDelegator
|
5
|
-
attr_reader :max_depth
|
6
|
-
|
7
|
-
def initialize(hash = {}, options = {})
|
8
|
-
fail ArgumentError, 'must be a Hash' unless hash.kind_of?(Hash)
|
9
|
-
@max_depth = options[:max_depth] || 20
|
10
|
-
super(hash)
|
11
|
-
sanitize(self)
|
12
|
-
end
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def sanitize(hash, depth = 0)
|
17
|
-
hash.each_pair do |k,v|
|
18
|
-
next unless v.kind_of?(Hash)
|
19
|
-
if depth >= max_depth
|
20
|
-
hash.delete(k)
|
21
|
-
else
|
22
|
-
hash[k] = sanitize(v, depth+1)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
hash
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
module Honeybadger
|
2
|
-
module Rack
|
3
|
-
# Middleware for Rack applications. Any errors raised by the upstream
|
4
|
-
# application will be delivered to Honeybadger and re-raised.
|
5
|
-
#
|
6
|
-
# Synopsis:
|
7
|
-
#
|
8
|
-
# require 'rack'
|
9
|
-
# require 'honeybadger'
|
10
|
-
#
|
11
|
-
# Honeybadger.configure do |config|
|
12
|
-
# config.api_key = 'my_api_key'
|
13
|
-
# end
|
14
|
-
#
|
15
|
-
# app = Rack::Builder.app do
|
16
|
-
# run lambda { |env| raise "Rack down" }
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
# use Honeybadger::Rack::ErrorNotifier
|
20
|
-
# run app
|
21
|
-
#
|
22
|
-
# Use a standard Honeybadger.configure call to configure your api key.
|
23
|
-
class ErrorNotifier
|
24
|
-
def initialize(app)
|
25
|
-
@app = app
|
26
|
-
Honeybadger.configuration.framework = "Rack: #{::Rack.release}"
|
27
|
-
end
|
28
|
-
|
29
|
-
def ignored_user_agent?(env)
|
30
|
-
true if Honeybadger.
|
31
|
-
configuration.
|
32
|
-
ignore_user_agent.
|
33
|
-
flatten.
|
34
|
-
any? { |ua| ua === env['HTTP_USER_AGENT'] }
|
35
|
-
end
|
36
|
-
|
37
|
-
def notify_honeybadger(exception,env)
|
38
|
-
Honeybadger.notify_or_ignore(exception, :rack_env => env) unless ignored_user_agent?(env)
|
39
|
-
end
|
40
|
-
|
41
|
-
def call(env)
|
42
|
-
begin
|
43
|
-
response = @app.call(env)
|
44
|
-
rescue Exception => raised
|
45
|
-
env['honeybadger.error_id'] = notify_honeybadger(raised, env)
|
46
|
-
raise
|
47
|
-
ensure
|
48
|
-
Honeybadger.context.clear!
|
49
|
-
end
|
50
|
-
|
51
|
-
framework_exception = env['rack.exception'] || env['sinatra.error']
|
52
|
-
if framework_exception
|
53
|
-
env['honeybadger.error_id'] = notify_honeybadger(framework_exception, env)
|
54
|
-
end
|
55
|
-
|
56
|
-
response
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|