bugsnag 2.7.1 → 2.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|