bugsnag 5.5.0 → 6.0.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.
- checksums.yaml +4 -4
- data/.travis.yml +33 -11
- data/CHANGELOG.md +23 -0
- data/Gemfile +20 -0
- data/Rakefile +19 -12
- data/UPGRADING.md +58 -0
- data/VERSION +1 -1
- data/bugsnag.gemspec +0 -9
- data/lib/bugsnag.rb +64 -86
- data/lib/bugsnag/configuration.rb +42 -26
- data/lib/bugsnag/delivery.rb +9 -0
- data/lib/bugsnag/delivery/synchronous.rb +3 -5
- data/lib/bugsnag/delivery/thread_queue.rb +4 -2
- data/lib/bugsnag/helpers.rb +5 -16
- data/lib/bugsnag/{delayed_job.rb → integrations/delayed_job.rb} +15 -7
- data/lib/bugsnag/{mailman.rb → integrations/mailman.rb} +13 -11
- data/lib/bugsnag/{que.rb → integrations/que.rb} +11 -11
- data/lib/bugsnag/{rack.rb → integrations/rack.rb} +22 -23
- data/lib/bugsnag/{rails → integrations/rails}/active_record_rescue.rb +9 -7
- data/lib/bugsnag/{rails → integrations/rails}/controller_methods.rb +0 -9
- data/lib/bugsnag/{railtie.rb → integrations/railtie.rb} +24 -21
- data/lib/bugsnag/{rake.rb → integrations/rake.rb} +12 -9
- data/lib/bugsnag/{resque.rb → integrations/resque.rb} +12 -9
- data/lib/bugsnag/integrations/shoryuken.rb +49 -0
- data/lib/bugsnag/{sidekiq.rb → integrations/sidekiq.rb} +13 -9
- data/lib/bugsnag/middleware/callbacks.rb +4 -8
- data/lib/bugsnag/middleware/classify_error.rb +7 -13
- data/lib/bugsnag/middleware/clearance_user.rb +8 -8
- data/lib/bugsnag/middleware/exception_meta_data.rb +34 -0
- data/lib/bugsnag/middleware/ignore_error_class.rb +21 -0
- data/lib/bugsnag/middleware/mailman.rb +4 -4
- data/lib/bugsnag/middleware/rack_request.rb +13 -13
- data/lib/bugsnag/middleware/rails3_request.rb +10 -10
- data/lib/bugsnag/middleware/rake.rb +5 -5
- data/lib/bugsnag/middleware/sidekiq.rb +5 -5
- data/lib/bugsnag/middleware/suggestion_data.rb +30 -0
- data/lib/bugsnag/middleware/warden_user.rb +6 -6
- data/lib/bugsnag/middleware_stack.rb +5 -5
- data/lib/bugsnag/report.rb +187 -0
- data/lib/bugsnag/stacktrace.rb +113 -0
- data/lib/bugsnag/tasks/bugsnag.rake +2 -70
- data/spec/cleaner_spec.rb +6 -0
- data/spec/configuration_spec.rb +1 -1
- data/spec/fixtures/middleware/internal_info_setter.rb +3 -3
- data/spec/fixtures/middleware/public_info_setter.rb +3 -3
- data/spec/fixtures/tasks/Rakefile +2 -3
- data/spec/integration_spec.rb +5 -20
- data/spec/{delayed_job_spec.rb → integrations/delayed_job_spec.rb} +0 -0
- data/spec/integrations/sidekiq_spec.rb +34 -0
- data/spec/middleware_spec.rb +108 -35
- data/spec/rack_spec.rb +1 -1
- data/spec/{notification_spec.rb → report_spec.rb} +226 -209
- data/spec/spec_helper.rb +18 -0
- data/spec/{code_spec.rb → stacktrace_spec.rb} +1 -1
- metadata +23 -139
- data/.document +0 -5
- data/lib/bugsnag/capistrano.rb +0 -7
- data/lib/bugsnag/capistrano2.rb +0 -32
- data/lib/bugsnag/delay/resque.rb +0 -21
- data/lib/bugsnag/deploy.rb +0 -35
- data/lib/bugsnag/middleware/rails2_request.rb +0 -52
- data/lib/bugsnag/notification.rb +0 -506
- data/lib/bugsnag/rails.rb +0 -70
- data/lib/bugsnag/rails/action_controller_rescue.rb +0 -74
- data/lib/bugsnag/shoryuken.rb +0 -41
- data/lib/bugsnag/tasks/bugsnag.cap +0 -48
- data/rails/init.rb +0 -7
@@ -4,25 +4,28 @@ Rake::TaskManager.record_task_metadata = true
|
|
4
4
|
|
5
5
|
class Rake::Task
|
6
6
|
|
7
|
+
FRAMEWORK_ATTRIBUTES = {
|
8
|
+
:framework => "Rake"
|
9
|
+
}
|
10
|
+
|
7
11
|
def execute_with_bugsnag(args=nil)
|
8
12
|
Bugsnag.configuration.app_type ||= "rake"
|
9
13
|
old_task = Bugsnag.configuration.request_data[:bugsnag_running_task]
|
10
|
-
Bugsnag.set_request_data :bugsnag_running_task, self
|
14
|
+
Bugsnag.configuration.set_request_data :bugsnag_running_task, self
|
11
15
|
|
12
16
|
execute_without_bugsnag(args)
|
13
17
|
|
14
18
|
rescue Exception => ex
|
15
|
-
Bugsnag.
|
16
|
-
|
17
|
-
|
18
|
-
:
|
19
|
-
|
20
|
-
}
|
19
|
+
Bugsnag.notify(ex, true) do |report|
|
20
|
+
report.severity = "error"
|
21
|
+
report.severity_reason = {
|
22
|
+
:type => Bugsnag::Report::UNHANDLED_EXCEPTION_MIDDLEWARE,
|
23
|
+
:attributes => FRAMEWORK_ATTRIBUTES
|
21
24
|
}
|
22
|
-
|
25
|
+
end
|
23
26
|
raise
|
24
27
|
ensure
|
25
|
-
Bugsnag.set_request_data :bugsnag_running_task, old_task
|
28
|
+
Bugsnag.configuration.set_request_data :bugsnag_running_task, old_task
|
26
29
|
end
|
27
30
|
|
28
31
|
alias_method :execute_without_bugsnag, :execute
|
@@ -3,6 +3,11 @@ require "resque/failure/multiple"
|
|
3
3
|
|
4
4
|
module Bugsnag
|
5
5
|
class Resque < ::Resque::Failure::Base
|
6
|
+
|
7
|
+
FRAMEWORK_ATTRIBUTES = {
|
8
|
+
:framework => "Resque"
|
9
|
+
}
|
10
|
+
|
6
11
|
def self.configure(&block)
|
7
12
|
add_failure_backend
|
8
13
|
Bugsnag.configure(&block)
|
@@ -26,16 +31,14 @@ module Bugsnag
|
|
26
31
|
end
|
27
32
|
|
28
33
|
def save
|
29
|
-
Bugsnag.
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
:
|
34
|
-
:attributes => {
|
35
|
-
:framework => "Resque"
|
36
|
-
}
|
34
|
+
Bugsnag.notify(exception, true) do |report|
|
35
|
+
report.severity = "error"
|
36
|
+
report.severity_reason = {
|
37
|
+
:type => Bugsnag::Report::UNHANDLED_EXCEPTION_MIDDLEWARE,
|
38
|
+
:attributes => FRAMEWORK_ATTRIBUTES
|
37
39
|
}
|
38
|
-
|
40
|
+
report.meta_data.merge!({:context => "#{payload['class']}@#{queue}", :payload => payload})
|
41
|
+
end
|
39
42
|
end
|
40
43
|
end
|
41
44
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'shoryuken'
|
2
|
+
|
3
|
+
module Bugsnag
|
4
|
+
class Shoryuken
|
5
|
+
|
6
|
+
FRAMEWORK_ATTRIBUTES = {
|
7
|
+
:framework => "Shoryuken"
|
8
|
+
}
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
Bugsnag.configure do |config|
|
12
|
+
config.app_type ||= "shoryuken"
|
13
|
+
config.default_delivery_method = :synchronous
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(_, queue, _, body)
|
18
|
+
begin
|
19
|
+
Bugsnag.before_notify_callbacks << lambda {|report|
|
20
|
+
report.add_tab(:shoryuken, {
|
21
|
+
queue: queue,
|
22
|
+
body: body
|
23
|
+
})
|
24
|
+
}
|
25
|
+
|
26
|
+
yield
|
27
|
+
rescue Exception => ex
|
28
|
+
unless [Interrupt, SystemExit, SignalException].include?(ex.class)
|
29
|
+
Bugsnag.auto_notify(ex, true) do |report|
|
30
|
+
report.severity = "error"
|
31
|
+
report.severity_reason = {
|
32
|
+
:type => Bugsnag::Report::UNHANDLED_EXCEPTION_MIDDLEWARE,
|
33
|
+
:attributes => Bugsnag::Shoryuken::FRAMEWORK_ATTRIBUTES
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
raise
|
38
|
+
ensure
|
39
|
+
Bugsnag.configuration.clear_request_data
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
::Shoryuken.configure_server do |config|
|
46
|
+
config.server_middleware do |chain|
|
47
|
+
chain.add ::Bugsnag::Shoryuken
|
48
|
+
end
|
49
|
+
end
|
@@ -2,6 +2,11 @@ require 'sidekiq'
|
|
2
2
|
|
3
3
|
module Bugsnag
|
4
4
|
class Sidekiq
|
5
|
+
|
6
|
+
FRAMEWORK_ATTRIBUTES = {
|
7
|
+
:framework => "Sidekiq"
|
8
|
+
}
|
9
|
+
|
5
10
|
def initialize
|
6
11
|
Bugsnag.configuration.internal_middleware.use(Bugsnag::Middleware::Sidekiq)
|
7
12
|
Bugsnag.configuration.app_type = "sidekiq"
|
@@ -11,22 +16,21 @@ module Bugsnag
|
|
11
16
|
def call(worker, msg, queue)
|
12
17
|
begin
|
13
18
|
# store msg/queue in thread local state to be read by Bugsnag::Middleware::Sidekiq
|
14
|
-
Bugsnag.set_request_data :sidekiq, { :msg => msg, :queue => queue }
|
19
|
+
Bugsnag.configuration.set_request_data :sidekiq, { :msg => msg, :queue => queue }
|
15
20
|
|
16
21
|
yield
|
17
22
|
rescue Exception => ex
|
18
23
|
raise ex if [Interrupt, SystemExit, SignalException].include? ex.class
|
19
|
-
Bugsnag.
|
20
|
-
|
21
|
-
|
22
|
-
:
|
23
|
-
|
24
|
-
}
|
24
|
+
Bugsnag.notify(ex, true) do |report|
|
25
|
+
report.severity = "error"
|
26
|
+
report.severity_reason = {
|
27
|
+
:type => Bugsnag::Report::UNHANDLED_EXCEPTION_MIDDLEWARE,
|
28
|
+
:attributes => FRAMEWORK_ATTRIBUTES
|
25
29
|
}
|
26
|
-
|
30
|
+
end
|
27
31
|
raise
|
28
32
|
ensure
|
29
|
-
Bugsnag.clear_request_data
|
33
|
+
Bugsnag.configuration.clear_request_data
|
30
34
|
end
|
31
35
|
end
|
32
36
|
end
|
@@ -4,16 +4,12 @@ module Bugsnag::Middleware
|
|
4
4
|
@bugsnag = bugsnag
|
5
5
|
end
|
6
6
|
|
7
|
-
def call(
|
8
|
-
if
|
9
|
-
|
7
|
+
def call(report)
|
8
|
+
if report.request_data[:before_callbacks]
|
9
|
+
report.request_data[:before_callbacks].each {|c| c.call(*[report][0...c.arity]) }
|
10
10
|
end
|
11
11
|
|
12
|
-
@bugsnag.call(
|
13
|
-
|
14
|
-
if notification.request_data[:after_callbacks]
|
15
|
-
notification.request_data[:after_callbacks].each {|c| c.call(*[notification][0...c.arity]) }
|
16
|
-
end
|
12
|
+
@bugsnag.call(report)
|
17
13
|
end
|
18
14
|
end
|
19
15
|
end
|
@@ -18,36 +18,30 @@ module Bugsnag::Middleware
|
|
18
18
|
@bugsnag = bugsnag
|
19
19
|
end
|
20
20
|
|
21
|
-
def call(
|
22
|
-
|
23
|
-
|
24
|
-
outer_break = false
|
21
|
+
def call(report)
|
22
|
+
report.raw_exceptions.each do |ex|
|
25
23
|
|
26
24
|
ancestor_chain = ex.class.ancestors.select {
|
27
|
-
|ancestor| ancestor.is_a?(Class)
|
25
|
+
|ancestor| ancestor.is_a?(Class)
|
28
26
|
}.map {
|
29
27
|
|ancestor| ancestor.to_s
|
30
28
|
}
|
31
29
|
|
32
30
|
INFO_CLASSES.each do |info_class|
|
33
31
|
if ancestor_chain.include?(info_class)
|
34
|
-
|
35
|
-
:type => Bugsnag::
|
32
|
+
report.severity_reason = {
|
33
|
+
:type => Bugsnag::Report::ERROR_CLASS,
|
36
34
|
:attributes => {
|
37
35
|
:errorClass => info_class
|
38
36
|
}
|
39
37
|
}
|
40
|
-
|
41
|
-
outer_break = true
|
38
|
+
report.severity = 'info'
|
42
39
|
break
|
43
40
|
end
|
44
41
|
end
|
45
|
-
|
46
|
-
break if outer_break
|
47
42
|
end
|
48
43
|
|
49
|
-
@bugsnag.call(
|
44
|
+
@bugsnag.call(report)
|
50
45
|
end
|
51
46
|
end
|
52
47
|
end
|
53
|
-
|
@@ -6,15 +6,15 @@ module Bugsnag::Middleware
|
|
6
6
|
@bugsnag = bugsnag
|
7
7
|
end
|
8
8
|
|
9
|
-
def call(
|
10
|
-
if
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
def call(report)
|
10
|
+
if report.request_data[:rack_env] &&
|
11
|
+
report.request_data[:rack_env]["clearance"] &&
|
12
|
+
report.request_data[:rack_env]["clearance"].signed_in? &&
|
13
|
+
report.request_data[:rack_env]["clearance"].current_user
|
14
14
|
|
15
15
|
# Extract useful user information
|
16
16
|
user = {}
|
17
|
-
user_object =
|
17
|
+
user_object = report.request_data[:rack_env]["clearance"].current_user
|
18
18
|
if user_object
|
19
19
|
# Build the bugsnag user info from the current user record
|
20
20
|
COMMON_USER_FIELDS.each do |field|
|
@@ -22,10 +22,10 @@ module Bugsnag::Middleware
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
|
25
|
+
report.user = user unless user.empty?
|
26
26
|
end
|
27
27
|
|
28
|
-
@bugsnag.call(
|
28
|
+
@bugsnag.call(report)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Bugsnag::Middleware
|
2
|
+
class ExceptionMetaData
|
3
|
+
def initialize(bugsnag)
|
4
|
+
@bugsnag = bugsnag
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(report)
|
8
|
+
# Apply the user's information attached to the exceptions
|
9
|
+
report.raw_exceptions.each do |exception|
|
10
|
+
if exception.class.include?(Bugsnag::MetaData)
|
11
|
+
if exception.bugsnag_user_id.is_a?(String)
|
12
|
+
report.user = {id: exception.bugsnag_user_id}
|
13
|
+
end
|
14
|
+
|
15
|
+
if exception.bugsnag_context.is_a?(String)
|
16
|
+
report.context = exception.bugsnag_context
|
17
|
+
end
|
18
|
+
|
19
|
+
if exception.bugsnag_grouping_hash.is_a?(String)
|
20
|
+
report.grouping_hash = exception.bugsnag_grouping_hash
|
21
|
+
end
|
22
|
+
|
23
|
+
if exception.respond_to?(:bugsnag_meta_data) && exception.bugsnag_meta_data
|
24
|
+
exception.bugsnag_meta_data.each do |key, value|
|
25
|
+
report.add_tab key, value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
@bugsnag.call(report)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Bugsnag::Middleware
|
2
|
+
class IgnoreErrorClass
|
3
|
+
def initialize(bugsnag)
|
4
|
+
@bugsnag = bugsnag
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(report)
|
8
|
+
ignore_error_class = report.raw_exceptions.any? do |ex|
|
9
|
+
ancestor_chain = ex.class.ancestors.select { |ancestor| ancestor.is_a?(Class) }.to_set
|
10
|
+
|
11
|
+
report.configuration.ignore_classes.any? do |to_ignore|
|
12
|
+
to_ignore.is_a?(Proc) ? to_ignore.call(ex) : ancestor_chain.include?(to_ignore)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
report.ignore! if ignore_error_class
|
17
|
+
|
18
|
+
@bugsnag.call(report)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -4,10 +4,10 @@ module Bugsnag::Middleware
|
|
4
4
|
@bugsnag = bugsnag
|
5
5
|
end
|
6
6
|
|
7
|
-
def call(
|
8
|
-
mailman_msg =
|
9
|
-
|
10
|
-
@bugsnag.call(
|
7
|
+
def call(report)
|
8
|
+
mailman_msg = report.request_data[:mailman_msg]
|
9
|
+
report.add_tab(:mailman, {"message" => mailman_msg}) if mailman_msg
|
10
|
+
@bugsnag.call(report)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -6,9 +6,9 @@ module Bugsnag::Middleware
|
|
6
6
|
@bugsnag = bugsnag
|
7
7
|
end
|
8
8
|
|
9
|
-
def call(
|
10
|
-
if
|
11
|
-
env =
|
9
|
+
def call(report)
|
10
|
+
if report.request_data[:rack_env]
|
11
|
+
env = report.request_data[:rack_env]
|
12
12
|
|
13
13
|
request = ::Rack::Request.new(env)
|
14
14
|
|
@@ -17,10 +17,10 @@ module Bugsnag::Middleware
|
|
17
17
|
session = env["rack.session"]
|
18
18
|
|
19
19
|
# Set the context
|
20
|
-
|
20
|
+
report.context = "#{request.request_method} #{request.path}"
|
21
21
|
|
22
22
|
# Set a sensible default for user_id
|
23
|
-
|
23
|
+
report.user["id"] = request.ip
|
24
24
|
|
25
25
|
# Build the clean url (hide the port if it is obvious)
|
26
26
|
url = "#{request.scheme}://#{request.host}"
|
@@ -28,9 +28,9 @@ module Bugsnag::Middleware
|
|
28
28
|
|
29
29
|
# If app is passed a bad URL, this code will crash attempting to clean it
|
30
30
|
begin
|
31
|
-
url << Bugsnag::Cleaner.new(
|
31
|
+
url << Bugsnag::Cleaner.new(report.configuration.meta_data_filters).clean_url(request.fullpath)
|
32
32
|
rescue StandardError => stde
|
33
|
-
Bugsnag.
|
33
|
+
Bugsnag.configuration.warn "RackRequest - Rescued error while cleaning request.fullpath: #{stde}"
|
34
34
|
end
|
35
35
|
|
36
36
|
headers = {}
|
@@ -48,7 +48,7 @@ module Bugsnag::Middleware
|
|
48
48
|
end
|
49
49
|
|
50
50
|
# Add a request tab
|
51
|
-
|
51
|
+
report.add_tab(:request, {
|
52
52
|
:url => url,
|
53
53
|
:httpMethod => request.request_method,
|
54
54
|
:params => params.to_hash,
|
@@ -58,23 +58,23 @@ module Bugsnag::Middleware
|
|
58
58
|
})
|
59
59
|
|
60
60
|
# Add an environment tab
|
61
|
-
if
|
62
|
-
|
61
|
+
if report.configuration.send_environment
|
62
|
+
report.add_tab(:environment, env)
|
63
63
|
end
|
64
64
|
|
65
65
|
# Add a session tab
|
66
66
|
if session
|
67
67
|
if session.is_a?(Hash)
|
68
68
|
# Rails 3
|
69
|
-
|
69
|
+
report.add_tab(:session, session)
|
70
70
|
elsif session.respond_to?(:to_hash)
|
71
71
|
# Rails 4
|
72
|
-
|
72
|
+
report.add_tab(:session, session.to_hash)
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
@bugsnag.call(
|
77
|
+
@bugsnag.call(report)
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
@@ -6,40 +6,40 @@ module Bugsnag::Middleware
|
|
6
6
|
@bugsnag = bugsnag
|
7
7
|
end
|
8
8
|
|
9
|
-
def call(
|
10
|
-
if
|
11
|
-
env =
|
9
|
+
def call(report)
|
10
|
+
if report.request_data[:rack_env]
|
11
|
+
env = report.request_data[:rack_env]
|
12
12
|
params = env["action_dispatch.request.parameters"]
|
13
13
|
client_ip = env["action_dispatch.remote_ip"].to_s rescue SPOOF
|
14
14
|
|
15
15
|
if params
|
16
16
|
# Set the context
|
17
|
-
|
17
|
+
report.context = "#{params[:controller]}##{params[:action]}"
|
18
18
|
|
19
19
|
# Augment the request tab
|
20
|
-
|
20
|
+
report.add_tab(:request, {
|
21
21
|
:railsAction => "#{params[:controller]}##{params[:action]}",
|
22
22
|
:params => params
|
23
23
|
})
|
24
24
|
end
|
25
25
|
|
26
26
|
# Use action_dispatch.remote_ip for IP address fields and send request id
|
27
|
-
|
27
|
+
report.add_tab(:request, {
|
28
28
|
:clientIp => client_ip,
|
29
29
|
:requestId => env["action_dispatch.request_id"]
|
30
30
|
})
|
31
31
|
|
32
|
-
|
32
|
+
report.user["id"] = client_ip
|
33
33
|
|
34
34
|
# Add the rails version
|
35
|
-
if
|
36
|
-
|
35
|
+
if report.configuration.send_environment
|
36
|
+
report.add_tab(:environment, {
|
37
37
|
:railsVersion => Rails::VERSION::STRING
|
38
38
|
})
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
@bugsnag.call(
|
42
|
+
@bugsnag.call(report)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
end
|