bugsnag 2.7.1 → 2.8.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/CHANGELOG.md +5 -0
- data/README.md +14 -3
- data/VERSION +1 -1
- data/lib/bugsnag.rb +18 -7
- data/lib/bugsnag/configuration.rb +3 -0
- data/lib/bugsnag/helpers.rb +37 -16
- data/lib/bugsnag/mailman.rb +5 -3
- data/lib/bugsnag/middleware/mailman.rb +13 -0
- data/lib/bugsnag/middleware/rails3_request.rb +1 -0
- data/lib/bugsnag/middleware/rake.rb +23 -0
- data/lib/bugsnag/middleware/sidekiq.rb +13 -0
- data/lib/bugsnag/notification.rb +39 -23
- data/lib/bugsnag/rack.rb +1 -6
- data/lib/bugsnag/rails/controller_methods.rb +3 -3
- data/lib/bugsnag/rake.rb +5 -16
- data/lib/bugsnag/sidekiq.rb +5 -4
- data/lib/bugsnag/tasks/bugsnag.rake +4 -1
- data/spec/fixtures/middleware/internal_info_setter.rb +11 -0
- data/spec/fixtures/middleware/public_info_setter.rb +11 -0
- data/spec/fixtures/tasks/Rakefile +15 -0
- data/spec/helper_spec.rb +16 -0
- data/spec/integration_spec.rb +11 -0
- data/spec/middleware_spec.rb +47 -14
- data/spec/notification_spec.rb +112 -2
- data/spec/spec_helper.rb +2 -1
- metadata +27 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b932122137e824fb015eec162c338d8936587af2
|
4
|
+
data.tar.gz: e9f4337e6858a184a8ab78e70f902971d4dcc318
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5438db3a7db9953df848433a36fd1da52e9e951cee37d8df226a87cd6b661c7bc843a2028c1280d2a2865d238e2a5b74e02af091c2cf725785eee1bba71f88c3
|
7
|
+
data.tar.gz: 95bb639e1d57e5f3b5b7aa61ba30c23047419b433f0a47b22af807865169cba7892a9887706314b364af87a1cc6c9ef4146dd5b6beb19bb9dc3c6dcda7a06c0d
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -83,7 +83,11 @@ exceptions, to help debug problems.
|
|
83
83
|
|
84
84
|
### Rails Apps
|
85
85
|
|
86
|
-
|
86
|
+
By default Bugsnag includes some information automatically. For example, we
|
87
|
+
send all the HTTP headers for requests. Additionally if you're using Warden or
|
88
|
+
Devise, the id, name and email of the current user are sent.
|
89
|
+
|
90
|
+
To send additional information, in any rails controller you can define a `before_bugsnag_notify` callback, which allows you to add this additional data by calling `add_tab` on the exception notification object. Please see the [Notification Object](#notification-object) for details on the notification parameter.
|
87
91
|
|
88
92
|
```ruby
|
89
93
|
class MyController < ApplicationController
|
@@ -639,10 +643,17 @@ introduced in.
|
|
639
643
|
### Using Heroku
|
640
644
|
|
641
645
|
You can easily add Bugsnag deploy tracking to your Heroku application by
|
642
|
-
running the following command:
|
646
|
+
running the following command from your application's directory:
|
647
|
+
|
648
|
+
```shell
|
649
|
+
$ bundle exec rake bugsnag:heroku:add_deploy_hook
|
650
|
+
```
|
651
|
+
|
652
|
+
If you have multiple Heroku apps, you can specify which app to add the hook
|
653
|
+
for as with the `HEROKU_APP` environment variable:
|
643
654
|
|
644
655
|
```shell
|
645
|
-
$ rake bugsnag:heroku:add_deploy_hook
|
656
|
+
$ bundle exec rake bugsnag:heroku:add_deploy_hook HEROKU_APP=my-app
|
646
657
|
```
|
647
658
|
|
648
659
|
### Using Capistrano
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.8.0
|
data/lib/bugsnag.rb
CHANGED
@@ -14,12 +14,14 @@ require "bugsnag/delivery/thread_queue"
|
|
14
14
|
require "bugsnag/rack"
|
15
15
|
require "bugsnag/railtie" if defined?(Rails::Railtie)
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
require "bugsnag/middleware/rack_request"
|
18
|
+
require "bugsnag/middleware/warden_user"
|
19
|
+
require "bugsnag/middleware/callbacks"
|
20
|
+
require "bugsnag/middleware/rails3_request"
|
21
|
+
require "bugsnag/middleware/sidekiq"
|
22
|
+
require "bugsnag/middleware/mailman"
|
23
|
+
require "bugsnag/middleware/rake"
|
24
|
+
require "bugsnag/middleware/callbacks"
|
23
25
|
|
24
26
|
module Bugsnag
|
25
27
|
LOG_PREFIX = "** [Bugsnag] "
|
@@ -47,7 +49,9 @@ module Bugsnag
|
|
47
49
|
|
48
50
|
# Explicitly notify of an exception
|
49
51
|
def notify(exception, overrides=nil, request_data=nil)
|
50
|
-
Notification.new(exception, configuration, overrides, request_data)
|
52
|
+
notification = Notification.new(exception, configuration, overrides, request_data)
|
53
|
+
notification.deliver
|
54
|
+
notification
|
51
55
|
end
|
52
56
|
|
53
57
|
# Notify of an exception unless it should be ignored
|
@@ -114,3 +118,10 @@ module Bugsnag
|
|
114
118
|
end
|
115
119
|
end
|
116
120
|
end
|
121
|
+
|
122
|
+
[:resque, :sidekiq, :mailman, :delayed_job].each do |integration|
|
123
|
+
begin
|
124
|
+
require "bugsnag/#{integration}"
|
125
|
+
rescue LoadError
|
126
|
+
end
|
127
|
+
end
|
@@ -20,6 +20,7 @@ module Bugsnag
|
|
20
20
|
attr_accessor :endpoint
|
21
21
|
attr_accessor :logger
|
22
22
|
attr_accessor :middleware
|
23
|
+
attr_accessor :internal_middleware
|
23
24
|
attr_accessor :delay_with_resque
|
24
25
|
attr_accessor :debug
|
25
26
|
attr_accessor :proxy_host
|
@@ -75,6 +76,8 @@ module Bugsnag
|
|
75
76
|
self.logger.level = Logger::WARN
|
76
77
|
|
77
78
|
# Configure the bugsnag middleware stack
|
79
|
+
self.internal_middleware = Bugsnag::MiddlewareStack.new
|
80
|
+
|
78
81
|
self.middleware = Bugsnag::MiddlewareStack.new
|
79
82
|
self.middleware.use Bugsnag::Middleware::Callbacks
|
80
83
|
end
|
data/lib/bugsnag/helpers.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
1
3
|
module Bugsnag
|
2
4
|
module Helpers
|
3
5
|
MAX_STRING_LENGTH = 4096
|
@@ -29,20 +31,10 @@ module Bugsnag
|
|
29
31
|
clean_hash
|
30
32
|
when Array, Set
|
31
33
|
obj.map { |el| cleanup_obj(el, filters, seen) }.compact
|
32
|
-
when Numeric
|
34
|
+
when Numeric, TrueClass, FalseClass
|
33
35
|
obj
|
34
36
|
when String
|
35
|
-
|
36
|
-
if obj.encoding == Encoding::UTF_8
|
37
|
-
obj.valid_encoding? ? obj : obj.encode('utf-16', {:invalid => :replace, :undef => :replace}).encode('utf-8')
|
38
|
-
else
|
39
|
-
obj.encode('utf-8', {:invalid => :replace, :undef => :replace})
|
40
|
-
end
|
41
|
-
elsif defined?(Iconv)
|
42
|
-
Iconv.conv('UTF-8//IGNORE', 'UTF-8', obj) || obj
|
43
|
-
else
|
44
|
-
obj
|
45
|
-
end
|
37
|
+
cleanup_string(obj)
|
46
38
|
else
|
47
39
|
str = obj.to_s
|
48
40
|
# avoid leaking potentially sensitive data from objects' #inspect output
|
@@ -54,6 +46,24 @@ module Bugsnag
|
|
54
46
|
end
|
55
47
|
end
|
56
48
|
|
49
|
+
def self.cleanup_string(str)
|
50
|
+
if defined?(str.encoding) && defined?(Encoding::UTF_8)
|
51
|
+
if str.encoding == Encoding::UTF_8
|
52
|
+
str.valid_encoding? ? str : str.encode('utf-16', {:invalid => :replace, :undef => :replace}).encode('utf-8')
|
53
|
+
else
|
54
|
+
str.encode('utf-8', {:invalid => :replace, :undef => :replace})
|
55
|
+
end
|
56
|
+
elsif defined?(Iconv)
|
57
|
+
Iconv.conv('UTF-8//IGNORE', 'UTF-8', str) || str
|
58
|
+
else
|
59
|
+
str
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.cleanup_obj_encoding(obj)
|
64
|
+
cleanup_obj(obj, nil)
|
65
|
+
end
|
66
|
+
|
57
67
|
def self.filters_match?(object, filters)
|
58
68
|
str = object.to_s
|
59
69
|
|
@@ -67,12 +77,23 @@ module Bugsnag
|
|
67
77
|
end
|
68
78
|
end
|
69
79
|
|
70
|
-
def self.cleanup_url(url, filters =
|
71
|
-
return url
|
80
|
+
def self.cleanup_url(url, filters = [])
|
81
|
+
return url if filters.empty?
|
72
82
|
|
73
|
-
|
83
|
+
uri = URI(url)
|
84
|
+
return url unless uri.query
|
85
|
+
|
86
|
+
query_params = uri.query.split('&').map { |pair| pair.split('=') }
|
87
|
+
query_params.map! do |key, val|
|
88
|
+
if filters_match?(key, filters)
|
89
|
+
"#{key}=[FILTERED]"
|
90
|
+
else
|
91
|
+
"#{key}=#{val}"
|
92
|
+
end
|
93
|
+
end
|
74
94
|
|
75
|
-
|
95
|
+
uri.query = query_params.join('&')
|
96
|
+
uri.to_s
|
76
97
|
end
|
77
98
|
|
78
99
|
def self.reduce_hash_size(hash)
|
data/lib/bugsnag/mailman.rb
CHANGED
@@ -4,9 +4,8 @@ module Bugsnag
|
|
4
4
|
class Mailman
|
5
5
|
def call(mail)
|
6
6
|
begin
|
7
|
-
|
8
|
-
|
9
|
-
}
|
7
|
+
|
8
|
+
Bugsnag.set_request_data :mailman_msg, mail.to_s
|
10
9
|
|
11
10
|
yield
|
12
11
|
rescue Exception => ex
|
@@ -20,6 +19,9 @@ module Bugsnag
|
|
20
19
|
end
|
21
20
|
end
|
22
21
|
|
22
|
+
|
23
23
|
if Mailman.config.respond_to?(:middleware)
|
24
24
|
Mailman.config.middleware.add ::Bugsnag::Mailman
|
25
25
|
end
|
26
|
+
|
27
|
+
Bugsnag.configuration.internal_middleware.use(Bugsnag::Middleware::Mailman)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Bugsnag::Middleware
|
2
|
+
class Mailman
|
3
|
+
def initialize(bugsnag)
|
4
|
+
@bugsnag = bugsnag
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(notification)
|
8
|
+
mailman_msg = notification.request_data[:mailman_msg]
|
9
|
+
notification.add_tab(:mailman, {"message" => mailman_msg}) if mailman_msg
|
10
|
+
@bugsnag.call(notification)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Bugsnag::Middleware
|
2
|
+
class Rake
|
3
|
+
def initialize(bugsnag)
|
4
|
+
@bugsnag = bugsnag
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(notification)
|
8
|
+
task = notification.request_data[:bugsnag_running_task]
|
9
|
+
|
10
|
+
if task
|
11
|
+
notification.add_tab(:rake_task, {
|
12
|
+
:name => task.name,
|
13
|
+
:description => task.full_comment,
|
14
|
+
:arguments => task.arg_description
|
15
|
+
})
|
16
|
+
|
17
|
+
notification.context ||= task.name
|
18
|
+
end
|
19
|
+
|
20
|
+
@bugsnag.call(notification)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Bugsnag::Middleware
|
2
|
+
class Sidekiq
|
3
|
+
def initialize(bugsnag)
|
4
|
+
@bugsnag = bugsnag
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(notification)
|
8
|
+
sidekiq = notification.request_data[:sidekiq]
|
9
|
+
notification.add_tab(:sidekiq, sidekiq) if sidekiq
|
10
|
+
@bugsnag.call(notification)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/bugsnag/notification.rb
CHANGED
@@ -1,4 +1,12 @@
|
|
1
1
|
require "multi_json"
|
2
|
+
|
3
|
+
if RUBY_VERSION =~ /^1\.8/
|
4
|
+
begin
|
5
|
+
require "iconv"
|
6
|
+
rescue LoadError
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
2
10
|
require "pathname"
|
3
11
|
|
4
12
|
module Bugsnag
|
@@ -183,32 +191,34 @@ module Bugsnag
|
|
183
191
|
# Warn if no release_stage is set
|
184
192
|
Bugsnag.warn "You should set your app's release_stage (see https://bugsnag.com/docs/notifiers/ruby#release_stage)." unless @configuration.release_stage
|
185
193
|
|
186
|
-
@
|
194
|
+
@configuration.internal_middleware.run(self) { }
|
187
195
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
exceptions.each do |exception|
|
196
|
-
if exception.class.include?(Bugsnag::MetaData)
|
197
|
-
if exception.bugsnag_user_id.is_a?(String)
|
198
|
-
self.user_id = exception.bugsnag_user_id
|
199
|
-
end
|
200
|
-
if exception.bugsnag_context.is_a?(String)
|
201
|
-
self.context = exception.bugsnag_context
|
202
|
-
end
|
196
|
+
exceptions.each do |exception|
|
197
|
+
if exception.class.include?(Bugsnag::MetaData)
|
198
|
+
if exception.bugsnag_user_id.is_a?(String)
|
199
|
+
self.user_id = exception.bugsnag_user_id
|
200
|
+
end
|
201
|
+
if exception.bugsnag_context.is_a?(String)
|
202
|
+
self.context = exception.bugsnag_context
|
203
203
|
end
|
204
204
|
end
|
205
|
+
end
|
205
206
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
end
|
207
|
+
[:user_id, :context, :user, :grouping_hash].each do |symbol|
|
208
|
+
if @overrides[symbol]
|
209
|
+
self.send("#{symbol}=", @overrides[symbol])
|
210
|
+
@overrides.delete symbol
|
211
211
|
end
|
212
|
+
end
|
213
|
+
|
214
|
+
# make meta_data available to public middleware
|
215
|
+
@meta_data = Bugsnag::Helpers.cleanup_obj(generate_meta_data(@exceptions, @overrides), @configuration.params_filters)
|
216
|
+
|
217
|
+
# Run the middleware here (including Bugsnag::Middleware::Callbacks)
|
218
|
+
# at the end of the middleware stack, execute the actual notification delivery
|
219
|
+
@configuration.middleware.run(self) do
|
220
|
+
# This supports self.ignore! for before_notify_callbacks.
|
221
|
+
return if @should_ignore
|
212
222
|
|
213
223
|
# Build the endpoint url
|
214
224
|
endpoint = (@configuration.use_ssl ? "https://" : "http://") + @configuration.endpoint
|
@@ -227,11 +237,17 @@ module Bugsnag
|
|
227
237
|
:exceptions => exception_list,
|
228
238
|
:severity => self.severity,
|
229
239
|
:groupingHash => self.grouping_hash,
|
230
|
-
|
231
|
-
}.reject {|k,v| v.nil? }
|
240
|
+
}
|
232
241
|
|
233
242
|
payload_event[:device] = {:hostname => @configuration.hostname} if @configuration.hostname
|
234
243
|
|
244
|
+
# cleanup character encodings
|
245
|
+
payload_event = Bugsnag::Helpers.cleanup_obj_encoding(payload_event)
|
246
|
+
|
247
|
+
# filter out sensitive values in (and cleanup encodings) metaData
|
248
|
+
payload_event[:metaData] = Bugsnag::Helpers.cleanup_obj(@meta_data, @configuration.params_filters)
|
249
|
+
payload_event.reject! {|k,v| v.nil? }
|
250
|
+
|
235
251
|
# Build the payload hash
|
236
252
|
payload = {
|
237
253
|
:apiKey => api_key,
|
data/lib/bugsnag/rack.rb
CHANGED
@@ -1,8 +1,3 @@
|
|
1
|
-
require "bugsnag/middleware/rack_request"
|
2
|
-
require "bugsnag/middleware/warden_user"
|
3
|
-
require "bugsnag/middleware/callbacks"
|
4
|
-
require "bugsnag/middleware/rails3_request"
|
5
|
-
|
6
1
|
module Bugsnag
|
7
2
|
class Rack
|
8
3
|
def initialize(app)
|
@@ -46,7 +41,7 @@ module Bugsnag
|
|
46
41
|
if env["rack.exception"]
|
47
42
|
Bugsnag.auto_notify(env["rack.exception"])
|
48
43
|
end
|
49
|
-
|
44
|
+
|
50
45
|
response
|
51
46
|
ensure
|
52
47
|
# Clear per-request data after processing the each request
|
@@ -3,9 +3,9 @@ module Bugsnag::Rails
|
|
3
3
|
def self.included(base)
|
4
4
|
base.extend ClassMethods
|
5
5
|
end
|
6
|
-
|
6
|
+
|
7
7
|
module ClassMethods
|
8
|
-
private
|
8
|
+
private
|
9
9
|
def before_bugsnag_notify(*methods, &block)
|
10
10
|
_add_bugsnag_notify_callback(:before_callbacks, *methods, &block)
|
11
11
|
end
|
@@ -41,4 +41,4 @@ module Bugsnag::Rails
|
|
41
41
|
Bugsnag.notify(exception, custom_data)
|
42
42
|
end
|
43
43
|
end
|
44
|
-
end
|
44
|
+
end
|
data/lib/bugsnag/rake.rb
CHANGED
@@ -11,38 +11,27 @@ module Bugsnag::Rake
|
|
11
11
|
alias_method :define_task, :bugsnag_define_task
|
12
12
|
end
|
13
13
|
end
|
14
|
-
|
15
|
-
Bugsnag.before_notify_callbacks << lambda {|notif|
|
16
|
-
task = Thread.current[:bugsnag_running_task]
|
17
|
-
next unless task
|
18
|
-
|
19
|
-
notif.add_tab(:rake_task, {
|
20
|
-
:name => task.name,
|
21
|
-
:description => task.full_comment,
|
22
|
-
:arguments => task.arg_description
|
23
|
-
})
|
24
|
-
|
25
|
-
notif.context ||= task.name
|
26
|
-
}
|
27
14
|
end
|
28
15
|
|
29
16
|
module ClassMethods
|
30
17
|
def bugsnag_define_task(*args, &block)
|
31
18
|
task = self.original_define_task(*args) do |*block_args|
|
32
19
|
begin
|
33
|
-
old_task =
|
34
|
-
|
20
|
+
old_task = Bugsnag.configuration.request_data[:bugsnag_running_task]
|
21
|
+
Bugsnag.set_request_data :bugsnag_running_task, task
|
35
22
|
|
36
23
|
yield(*block_args) if block_given?
|
37
24
|
rescue Exception => e
|
38
25
|
Bugsnag.auto_notify(e)
|
39
26
|
raise
|
40
27
|
ensure
|
41
|
-
|
28
|
+
Bugsnag.set_request_data :bugsnag_running_task, old_task
|
42
29
|
end
|
43
30
|
end
|
44
31
|
end
|
45
32
|
end
|
46
33
|
end
|
47
34
|
|
35
|
+
Bugsnag.configuration.internal_middleware.use(Bugsnag::Middleware::Rake)
|
36
|
+
|
48
37
|
Rake::Task.send(:include, Bugsnag::Rake) if defined?(Rake::Task)
|
data/lib/bugsnag/sidekiq.rb
CHANGED
@@ -4,10 +4,9 @@ module Bugsnag
|
|
4
4
|
class Sidekiq
|
5
5
|
def call(worker, msg, queue)
|
6
6
|
begin
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
}
|
7
|
+
|
8
|
+
# store msg/queue in thread local state to be read by Bugsnag::Middleware::Sidekiq
|
9
|
+
Bugsnag.set_request_data :sidekiq, { :msg => msg, :queue => queue }
|
11
10
|
|
12
11
|
yield
|
13
12
|
rescue Exception => ex
|
@@ -34,3 +33,5 @@ else
|
|
34
33
|
end
|
35
34
|
end
|
36
35
|
end
|
36
|
+
|
37
|
+
Bugsnag.configuration.internal_middleware.use(Bugsnag::Middleware::Sidekiq)
|
@@ -45,7 +45,9 @@ namespace :bugsnag do
|
|
45
45
|
}
|
46
46
|
|
47
47
|
# Fetch heroku config settings
|
48
|
-
|
48
|
+
config_command = "heroku config --shell"
|
49
|
+
config_command += " --app #{ENV["HEROKU_APP"]}" if ENV["HEROKU_APP"]
|
50
|
+
heroku_env = run_command.call(config_command).split(/[\n\r]/).each_with_object({}) do |c, obj|
|
49
51
|
k,v = c.split("=")
|
50
52
|
obj[k] = v.strip.empty? ? nil : v
|
51
53
|
end
|
@@ -71,6 +73,7 @@ namespace :bugsnag do
|
|
71
73
|
# Add the hook
|
72
74
|
url = "https://notify.bugsnag.com/deploy?" + params.map {|k,v| "#{k}=#{v}"}.join("&")
|
73
75
|
command = "heroku addons:add deployhooks:http --url=\"#{url}\""
|
76
|
+
command += " --app #{ENV["HEROKU_APP"]}" if ENV["HEROKU_APP"]
|
74
77
|
|
75
78
|
puts "$ #{command}"
|
76
79
|
run_command.call(command)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "bugsnag/rake"
|
2
|
+
|
3
|
+
namespace :test do
|
4
|
+
desc "used by integration_spec to test that Bugsnag::Middleware::Rake runs properly"
|
5
|
+
task :crash do
|
6
|
+
port = ENV['BUGSNAG_TEST_SERVER_PORT']
|
7
|
+
Bugsnag.configure do |config|
|
8
|
+
config.endpoint = "localhost:#{port}"
|
9
|
+
config.api_key = "0" * 32
|
10
|
+
config.use_ssl = false
|
11
|
+
end
|
12
|
+
|
13
|
+
raise
|
14
|
+
end
|
15
|
+
end
|
data/spec/helper_spec.rb
CHANGED
@@ -114,4 +114,20 @@ describe Bugsnag::Helpers do
|
|
114
114
|
|
115
115
|
expect(url).to eq("/dir/page?param1=[FILTERED]¶m2=[FILTERED]¶m3=value3")
|
116
116
|
end
|
117
|
+
|
118
|
+
it "filters using a combination of string and regex filters" do
|
119
|
+
url = Bugsnag::Helpers.cleanup_url "/dir/page?param1=value1¶m2=value2¶m3=value3", ["param1", /param2/]
|
120
|
+
|
121
|
+
expect(url).to eq("/dir/page?param1=[FILTERED]¶m2=[FILTERED]¶m3=value3")
|
122
|
+
end
|
123
|
+
|
124
|
+
it "filters regex matches" do
|
125
|
+
url = Bugsnag::Helpers.cleanup_url "https://host.example/sessions?access_token=abc123", [/\Aaccess_token\z/]
|
126
|
+
expect(url).to eq("https://host.example/sessions?access_token=[FILTERED]")
|
127
|
+
end
|
128
|
+
|
129
|
+
it "filters partial regex matches" do
|
130
|
+
url = Bugsnag::Helpers.cleanup_url "https://host.example/sessions?access_token=abc123", [/token/]
|
131
|
+
expect(url).to eq("https://host.example/sessions?access_token=[FILTERED]")
|
132
|
+
end
|
117
133
|
end
|
data/spec/integration_spec.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'webrick'
|
2
2
|
require 'spec_helper'
|
3
|
+
require 'json'
|
3
4
|
|
4
5
|
describe 'Bugsnag' do
|
5
6
|
server = nil
|
@@ -20,6 +21,16 @@ describe 'Bugsnag' do
|
|
20
21
|
|
21
22
|
let(:request) { JSON.parse(queue.pop) }
|
22
23
|
|
24
|
+
it 'should run the rake middleware when rake tasks crash' do
|
25
|
+
ENV['BUGSNAG_TEST_SERVER_PORT'] = server.config[:Port].to_s
|
26
|
+
task_fixtures_path = File.join(File.dirname(__FILE__), 'fixtures', 'tasks')
|
27
|
+
Dir.chdir(task_fixtures_path) do
|
28
|
+
system("bundle exec rake test:crash > /dev/null 2>&1")
|
29
|
+
end
|
30
|
+
expect(request["events"][0]["metaData"]["rake_task"]).not_to be_nil
|
31
|
+
expect(request["events"][0]["metaData"]["rake_task"]["name"]).to eq("test:crash")
|
32
|
+
end
|
33
|
+
|
23
34
|
it 'should send notifications over the wire' do
|
24
35
|
Bugsnag.configure do |config|
|
25
36
|
config.endpoint = "localhost:#{server.config[:Port]}"
|
data/spec/middleware_spec.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'fixtures/middleware/public_info_setter'
|
3
|
+
require 'fixtures/middleware/internal_info_setter'
|
2
4
|
|
3
5
|
describe Bugsnag::MiddlewareStack do
|
4
6
|
it "runs before_bugsnag_notify callbacks, adding a tab" do
|
@@ -65,23 +67,28 @@ describe Bugsnag::MiddlewareStack do
|
|
65
67
|
|
66
68
|
end
|
67
69
|
|
68
|
-
it "overrides
|
70
|
+
it "allows overrides to override values set by internal middleware" do
|
71
|
+
Bugsnag.configuration.internal_middleware.use(InternalInfoSetter)
|
72
|
+
Bugsnag.notify(BugsnagTestException.new("It crashed"), {:info => "overridden"})
|
69
73
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
callback_run_count += 1
|
74
|
+
expect(Bugsnag).to have_sent_notification{ |payload|
|
75
|
+
event = get_event_from_payload(payload)
|
76
|
+
expect(event["metaData"]["custom"]).not_to be_nil
|
77
|
+
expect(event["metaData"]["custom"]["info"]).not_to eq(InternalInfoSetter::MESSAGE)
|
78
|
+
expect(event["metaData"]["custom"]["info"]).to eq("overridden")
|
76
79
|
}
|
80
|
+
end
|
81
|
+
|
82
|
+
it "doesn't allow overrides to override public middleware" do
|
83
|
+
Bugsnag.configuration.middleware.use(PublicInfoSetter)
|
84
|
+
|
85
|
+
Bugsnag.notify(BugsnagTestException.new("It crashed"), {:info => "overridden"})
|
77
86
|
|
78
|
-
Bugsnag.notify(BugsnagTestException.new("It crashed"), {:info => "here2"})
|
79
|
-
expect(callback_run_count).to eq(1)
|
80
87
|
expect(Bugsnag).to have_sent_notification{ |payload|
|
81
88
|
event = get_event_from_payload(payload)
|
82
89
|
expect(event["metaData"]["custom"]).not_to be_nil
|
83
|
-
expect(event["metaData"]["custom"]["info"]).
|
84
|
-
expect(event["metaData"]["custom"]["
|
90
|
+
expect(event["metaData"]["custom"]["info"]).not_to eq("overridden")
|
91
|
+
expect(event["metaData"]["custom"]["info"]).to eq(PublicInfoSetter::MESSAGE)
|
85
92
|
}
|
86
93
|
end
|
87
94
|
|
@@ -93,7 +100,6 @@ describe Bugsnag::MiddlewareStack do
|
|
93
100
|
event = get_event_from_payload(payload)
|
94
101
|
expect(event["metaData"].size).to eq(0)
|
95
102
|
}
|
96
|
-
|
97
103
|
end
|
98
104
|
|
99
105
|
it "runs after_bugsnag_notify callbacks" do
|
@@ -105,7 +111,7 @@ describe Bugsnag::MiddlewareStack do
|
|
105
111
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
106
112
|
|
107
113
|
expect(callback_run_count).to eq(1)
|
108
|
-
expect(Bugsnag::Notification).to have_sent_notification
|
114
|
+
expect(Bugsnag::Notification).to have_sent_notification { }
|
109
115
|
end
|
110
116
|
|
111
117
|
it "does not execute disabled bugsnag middleware" do
|
@@ -127,7 +133,7 @@ describe Bugsnag::MiddlewareStack do
|
|
127
133
|
notif.ignore!
|
128
134
|
end
|
129
135
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
130
|
-
expect(Bugsnag::Notification).not_to have_sent_notification
|
136
|
+
expect(Bugsnag::Notification).not_to have_sent_notification { }
|
131
137
|
end
|
132
138
|
|
133
139
|
it "allows inspection of meta_data before ignoring exception" do
|
@@ -145,4 +151,31 @@ describe Bugsnag::MiddlewareStack do
|
|
145
151
|
expect(Bugsnag::Notification).not_to have_sent_notification
|
146
152
|
|
147
153
|
end
|
154
|
+
|
155
|
+
it "allows meta_data to be modified in a middleware" do
|
156
|
+
MetaDataMunger = Class.new do
|
157
|
+
def initialize(bugsnag)
|
158
|
+
@bugsnag = bugsnag
|
159
|
+
end
|
160
|
+
|
161
|
+
def call(notification)
|
162
|
+
token = notification.meta_data[:sidekiq][:args].first
|
163
|
+
notification.meta_data[:sidekiq][:args] = ["#{token[0...6]}*****#{token[-4..-1]}"]
|
164
|
+
@bugsnag.call(notification)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
Bugsnag.configure do |c|
|
169
|
+
c.middleware.use MetaDataMunger
|
170
|
+
end
|
171
|
+
|
172
|
+
notification = Bugsnag.notify(BugsnagTestException.new("It crashed"), {
|
173
|
+
:sidekiq => {
|
174
|
+
:args => ["abcdef123456abcdef123456abcdef123456"]
|
175
|
+
}
|
176
|
+
})
|
177
|
+
|
178
|
+
expect(notification.meta_data[:sidekiq][:args]).to eq(["abcdef*****3456"])
|
179
|
+
end
|
180
|
+
|
148
181
|
end
|
data/spec/notification_spec.rb
CHANGED
@@ -267,8 +267,8 @@ describe Bugsnag::Notification do
|
|
267
267
|
|
268
268
|
expect(Bugsnag).to have_sent_notification{ |payload|
|
269
269
|
# Truncated body should be no bigger than
|
270
|
-
# 2 truncated hashes (4096*2) + rest of payload (
|
271
|
-
expect(Bugsnag::Helpers.dump_json(payload).length).to be < 4096*2 +
|
270
|
+
# 2 truncated hashes (4096*2) + rest of payload (20000)
|
271
|
+
expect(Bugsnag::Helpers.dump_json(payload).length).to be < 4096*2 + 20000
|
272
272
|
}
|
273
273
|
end
|
274
274
|
|
@@ -660,6 +660,116 @@ describe Bugsnag::Notification do
|
|
660
660
|
}
|
661
661
|
end
|
662
662
|
|
663
|
+
it "should handle utf8 encoding errors in exceptions_list" do
|
664
|
+
invalid_data = "\"foo\xEBbar\""
|
665
|
+
invalid_data = invalid_data.force_encoding("utf-8") if invalid_data.respond_to?(:force_encoding)
|
666
|
+
|
667
|
+
begin
|
668
|
+
JSON.parse(invalid_data)
|
669
|
+
rescue
|
670
|
+
Bugsnag.notify $!
|
671
|
+
end
|
672
|
+
|
673
|
+
expect(Bugsnag).to have_sent_notification { |payload|
|
674
|
+
if defined?(Encoding::UTF_8)
|
675
|
+
expect(payload.to_json).to match(/foo�bar/)
|
676
|
+
else
|
677
|
+
expect(payload.to_json).to match(/foobar/)
|
678
|
+
end
|
679
|
+
}
|
680
|
+
end
|
681
|
+
|
682
|
+
it "should handle utf8 encoding errors in notification context" do
|
683
|
+
invalid_data = "\"foo\xEBbar\""
|
684
|
+
invalid_data = invalid_data.force_encoding("utf-8") if invalid_data.respond_to?(:force_encoding)
|
685
|
+
|
686
|
+
begin
|
687
|
+
raise
|
688
|
+
rescue
|
689
|
+
Bugsnag.notify($!, { :context => invalid_data })
|
690
|
+
end
|
691
|
+
|
692
|
+
expect(Bugsnag).to have_sent_notification { |payload|
|
693
|
+
if defined?(Encoding::UTF_8)
|
694
|
+
expect(payload.to_json).to match(/foo�bar/)
|
695
|
+
else
|
696
|
+
expect(payload.to_json).to match(/foobar/)
|
697
|
+
end
|
698
|
+
}
|
699
|
+
end
|
700
|
+
|
701
|
+
it "should handle utf8 encoding errors in notification app fields" do
|
702
|
+
invalid_data = "\"foo\xEBbar\""
|
703
|
+
invalid_data = invalid_data.force_encoding("utf-8") if invalid_data.respond_to?(:force_encoding)
|
704
|
+
|
705
|
+
Bugsnag.configuration.app_version = invalid_data
|
706
|
+
Bugsnag.configuration.release_stage = invalid_data
|
707
|
+
Bugsnag.configuration.app_type = invalid_data
|
708
|
+
|
709
|
+
begin
|
710
|
+
raise
|
711
|
+
rescue
|
712
|
+
Bugsnag.notify $!
|
713
|
+
end
|
714
|
+
|
715
|
+
expect(Bugsnag).to have_sent_notification { |payload|
|
716
|
+
if defined?(Encoding::UTF_8)
|
717
|
+
expect(payload.to_json).to match(/foo�bar/)
|
718
|
+
else
|
719
|
+
expect(payload.to_json).to match(/foobar/)
|
720
|
+
end
|
721
|
+
}
|
722
|
+
end
|
723
|
+
|
724
|
+
it "should handle utf8 encoding errors in grouping_hash" do
|
725
|
+
invalid_data = "\"foo\xEBbar\""
|
726
|
+
invalid_data = invalid_data.force_encoding("utf-8") if invalid_data.respond_to?(:force_encoding)
|
727
|
+
|
728
|
+
Bugsnag.before_notify_callbacks << lambda do |notif|
|
729
|
+
notif.grouping_hash = invalid_data
|
730
|
+
end
|
731
|
+
|
732
|
+
begin
|
733
|
+
raise
|
734
|
+
rescue
|
735
|
+
Bugsnag.notify $!
|
736
|
+
end
|
737
|
+
|
738
|
+
expect(Bugsnag).to have_sent_notification { |payload|
|
739
|
+
if defined?(Encoding::UTF_8)
|
740
|
+
expect(payload.to_json).to match(/foo�bar/)
|
741
|
+
else
|
742
|
+
expect(payload.to_json).to match(/foobar/)
|
743
|
+
end
|
744
|
+
}
|
745
|
+
end
|
746
|
+
|
747
|
+
it "should handle utf8 encoding errors in notification user fields" do
|
748
|
+
invalid_data = "\"foo\xEBbar\""
|
749
|
+
invalid_data = invalid_data.force_encoding("utf-8") if invalid_data.respond_to?(:force_encoding)
|
750
|
+
|
751
|
+
Bugsnag.before_notify_callbacks << lambda do |notif|
|
752
|
+
notif.user = {
|
753
|
+
:email => "#{invalid_data}@foo.com",
|
754
|
+
:name => invalid_data
|
755
|
+
}
|
756
|
+
end
|
757
|
+
|
758
|
+
begin
|
759
|
+
raise
|
760
|
+
rescue
|
761
|
+
Bugsnag.notify $!
|
762
|
+
end
|
763
|
+
|
764
|
+
expect(Bugsnag).to have_sent_notification { |payload|
|
765
|
+
if defined?(Encoding::UTF_8)
|
766
|
+
expect(payload.to_json).to match(/foo�bar/)
|
767
|
+
else
|
768
|
+
expect(payload.to_json).to match(/foobar/)
|
769
|
+
end
|
770
|
+
}
|
771
|
+
end
|
772
|
+
|
663
773
|
if defined?(JRUBY_VERSION)
|
664
774
|
|
665
775
|
it "should work with java.lang.Throwables" do
|
data/spec/spec_helper.rb
CHANGED
@@ -45,8 +45,9 @@ def have_sent_notification(&matcher)
|
|
45
45
|
have_requested(:post, "https://notify.bugsnag.com/").with do |request|
|
46
46
|
if matcher
|
47
47
|
matcher.call JSON.parse(request.body)
|
48
|
-
else
|
49
48
|
true
|
49
|
+
else
|
50
|
+
raise "no matcher provided to have_sent_notification (did you use { })"
|
50
51
|
end
|
51
52
|
end
|
52
53
|
end
|
metadata
CHANGED
@@ -1,97 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bugsnag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Smith
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_json
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - '>='
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rdoc
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: pry
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - '>='
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - '>='
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: webmock
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - '>='
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - '>='
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
description: Ruby notifier for bugsnag.com
|
@@ -102,10 +102,10 @@ extra_rdoc_files:
|
|
102
102
|
- LICENSE.txt
|
103
103
|
- README.md
|
104
104
|
files:
|
105
|
-
-
|
106
|
-
-
|
107
|
-
-
|
108
|
-
-
|
105
|
+
- .document
|
106
|
+
- .gitignore
|
107
|
+
- .rspec
|
108
|
+
- .travis.yml
|
109
109
|
- CHANGELOG.md
|
110
110
|
- Gemfile
|
111
111
|
- LICENSE.txt
|
@@ -127,9 +127,12 @@ files:
|
|
127
127
|
- lib/bugsnag/mailman.rb
|
128
128
|
- lib/bugsnag/meta_data.rb
|
129
129
|
- lib/bugsnag/middleware/callbacks.rb
|
130
|
+
- lib/bugsnag/middleware/mailman.rb
|
130
131
|
- lib/bugsnag/middleware/rack_request.rb
|
131
132
|
- lib/bugsnag/middleware/rails2_request.rb
|
132
133
|
- lib/bugsnag/middleware/rails3_request.rb
|
134
|
+
- lib/bugsnag/middleware/rake.rb
|
135
|
+
- lib/bugsnag/middleware/sidekiq.rb
|
133
136
|
- lib/bugsnag/middleware/warden_user.rb
|
134
137
|
- lib/bugsnag/middleware_stack.rb
|
135
138
|
- lib/bugsnag/notification.rb
|
@@ -152,6 +155,9 @@ files:
|
|
152
155
|
- spec/fixtures/crashes/end_of_file.rb
|
153
156
|
- spec/fixtures/crashes/short_file.rb
|
154
157
|
- spec/fixtures/crashes/start_of_file.rb
|
158
|
+
- spec/fixtures/middleware/internal_info_setter.rb
|
159
|
+
- spec/fixtures/middleware/public_info_setter.rb
|
160
|
+
- spec/fixtures/tasks/Rakefile
|
155
161
|
- spec/helper_spec.rb
|
156
162
|
- spec/integration_spec.rb
|
157
163
|
- spec/middleware_spec.rb
|
@@ -168,17 +174,17 @@ require_paths:
|
|
168
174
|
- lib
|
169
175
|
required_ruby_version: !ruby/object:Gem::Requirement
|
170
176
|
requirements:
|
171
|
-
- -
|
177
|
+
- - '>='
|
172
178
|
- !ruby/object:Gem::Version
|
173
179
|
version: '0'
|
174
180
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
175
181
|
requirements:
|
176
|
-
- -
|
182
|
+
- - '>='
|
177
183
|
- !ruby/object:Gem::Version
|
178
184
|
version: '0'
|
179
185
|
requirements: []
|
180
186
|
rubyforge_project:
|
181
|
-
rubygems_version: 2.
|
187
|
+
rubygems_version: 2.0.14
|
182
188
|
signing_key:
|
183
189
|
specification_version: 4
|
184
190
|
summary: Ruby notifier for bugsnag.com
|