bugsnag 1.8.6 → 1.8.7
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/.gitignore +2 -1
- data/CHANGELOG.md +7 -0
- data/README.md +11 -5
- data/VERSION +1 -1
- data/bugsnag.gemspec +2 -1
- data/lib/bugsnag/notification.rb +15 -1
- data/lib/bugsnag/tasks/bugsnag.cap +4 -1
- data/lib/bugsnag/tasks/bugsnag.rake +15 -11
- data/spec/helper_spec.rb +30 -30
- data/spec/middleware_spec.rb +37 -39
- data/spec/notification_spec.rb +227 -212
- data/spec/rack_spec.rb +9 -9
- data/spec/spec_helper.rb +4 -2
- metadata +24 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d1ded05b67617d43a3ec3d4201f289268e557532
|
4
|
+
data.tar.gz: f555a022921c989415992c649dde17f669c4ee2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc89fe2fe2a176e82b130159968bafa9ccba23408ec648dd76a4a1fa81bae287866fce45aad2cbf53e7a16aa0c2db7fadc0819bde435b11bbde2db892af28841
|
7
|
+
data.tar.gz: 7c8e42b005712c3817a48c79641396cbb01975d5ff4ee0ddb39a35354ed1db75bad4df9a7643c8c31df2e0f3ff85d43487fc2e120a9ecdfdfa66f74ee577e3e4
|
data/.gitignore
CHANGED
@@ -16,7 +16,8 @@ Gemfile.lock
|
|
16
16
|
pkg
|
17
17
|
*.gem
|
18
18
|
|
19
|
-
|
19
|
+
vendor
|
20
|
+
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
20
21
|
#
|
21
22
|
# * Create a file at ~/.gitignore
|
22
23
|
# * Include files you want ignored
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -470,6 +470,17 @@ rescue => e
|
|
470
470
|
end
|
471
471
|
```
|
472
472
|
|
473
|
+
### Grouping hash
|
474
|
+
|
475
|
+
If you want to override Bugsnag's grouping algorithm, you can specify a grouping hash key as a parameter to `Bugsnag.notify`:
|
476
|
+
|
477
|
+
```ruby
|
478
|
+
rescue => e
|
479
|
+
Bugsnag.notify e, grouping_hash: "this-is-my-grouping-hash"
|
480
|
+
end
|
481
|
+
```
|
482
|
+
|
483
|
+
All errors with the same groupingHash will be grouped together within the bugsnag dashboard.
|
473
484
|
|
474
485
|
Deploy Tracking
|
475
486
|
---------------
|
@@ -515,23 +526,18 @@ additional deploy information:
|
|
515
526
|
The release stage (eg, production, staging) currently being deployed.
|
516
527
|
This is set automatically from your Bugsnag settings or rails/rack
|
517
528
|
environment.
|
518
|
-
|
519
529
|
- **BUGSNAG_API_KEY** -
|
520
530
|
Your Bugsnag API key. This is set automatically from your Bugsnag
|
521
531
|
settings in your app.
|
522
|
-
|
523
532
|
- **BUGSNAG_REPOSITORY** -
|
524
533
|
The repository from which you are deploying the code. This is set
|
525
534
|
automatically if you are using capistrano.
|
526
|
-
|
527
535
|
- **BUGSNAG_BRANCH** -
|
528
536
|
The source control branch from which you are deploying the code.
|
529
537
|
This is set automatically if you are using capistrano.
|
530
|
-
|
531
538
|
- **BUGSNAG_REVISION** -
|
532
539
|
The source control revision for the code you are currently deploying.
|
533
540
|
This is set automatically if you are using capistrano.
|
534
|
-
|
535
541
|
- **BUGSNAG_APP_VERSION** -
|
536
542
|
The app version of the code you are currently deploying. Only set this
|
537
543
|
if you tag your releases with [semantic version numbers](http://semver.org/)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.8.
|
1
|
+
1.8.7
|
data/bugsnag.gemspec
CHANGED
@@ -22,12 +22,13 @@ Gem::Specification.new do |s|
|
|
22
22
|
if RUBY_VERSION < "1.9"
|
23
23
|
# Use ruby 1.8 compatible httparty
|
24
24
|
s.add_runtime_dependency 'httparty', ["< 0.12.0", ">= 0.6"]
|
25
|
+
s.add_development_dependency "rake", "~> 10.1.1"
|
25
26
|
else
|
26
27
|
s.add_runtime_dependency 'httparty', ["< 1.0", ">= 0.6"]
|
28
|
+
s.add_development_dependency 'rake'
|
27
29
|
end
|
28
30
|
|
29
31
|
s.add_development_dependency 'rspec'
|
30
32
|
s.add_development_dependency 'rdoc'
|
31
|
-
s.add_development_dependency 'rake'
|
32
33
|
end
|
33
34
|
|
data/lib/bugsnag/notification.rb
CHANGED
@@ -59,6 +59,11 @@ module Bugsnag
|
|
59
59
|
self.severity = @overrides[:severity]
|
60
60
|
@overrides.delete :severity
|
61
61
|
|
62
|
+
if @overrides.key? :grouping_hash
|
63
|
+
self.grouping_hash = @overrides[:grouping_hash]
|
64
|
+
@overrides.delete :grouping_hash
|
65
|
+
end
|
66
|
+
|
62
67
|
if @overrides.key? :api_key
|
63
68
|
self.api_key = @overrides[:api_key]
|
64
69
|
@overrides.delete :api_key
|
@@ -143,6 +148,14 @@ module Bugsnag
|
|
143
148
|
@severity || "error"
|
144
149
|
end
|
145
150
|
|
151
|
+
def grouping_hash=(grouping_hash)
|
152
|
+
@grouping_hash = grouping_hash
|
153
|
+
end
|
154
|
+
|
155
|
+
def grouping_hash
|
156
|
+
@grouping_hash || nil
|
157
|
+
end
|
158
|
+
|
146
159
|
def api_key=(api_key)
|
147
160
|
@api_key = api_key
|
148
161
|
end
|
@@ -183,7 +196,7 @@ module Bugsnag
|
|
183
196
|
end
|
184
197
|
end
|
185
198
|
|
186
|
-
[:user_id, :context, :user].each do |symbol|
|
199
|
+
[:user_id, :context, :user, :grouping_hash].each do |symbol|
|
187
200
|
if @overrides[symbol]
|
188
201
|
self.send("#{symbol}=", @overrides[symbol])
|
189
202
|
@overrides.delete symbol
|
@@ -205,6 +218,7 @@ module Bugsnag
|
|
205
218
|
:user => @user,
|
206
219
|
:exceptions => exception_list,
|
207
220
|
:severity => self.severity,
|
221
|
+
:groupingHash => self.grouping_hash,
|
208
222
|
:metaData => Bugsnag::Helpers.cleanup_obj(generate_meta_data(@exceptions, @overrides), @configuration.params_filters)
|
209
223
|
}.reject {|k,v| v.nil? }
|
210
224
|
|
@@ -44,7 +44,9 @@ namespace :bugsnag do
|
|
44
44
|
|
45
45
|
within release_path do
|
46
46
|
with rails_env: rails_env do
|
47
|
-
|
47
|
+
params = "bugsnag:deploy #{new_env.map{|k,v| "#{k}=#{v}"}.join(" ")}"
|
48
|
+
rake = fetch(:rake, "rake")
|
49
|
+
execute rake, params
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
@@ -53,3 +55,4 @@ namespace :bugsnag do
|
|
53
55
|
end
|
54
56
|
|
55
57
|
end
|
58
|
+
# vi:ft=ruby
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "bugsnag"
|
2
|
+
require "pathname"
|
2
3
|
require "httparty"
|
3
4
|
require "multi_json"
|
4
5
|
require "net/http"
|
@@ -11,17 +12,20 @@ namespace :bugsnag do
|
|
11
12
|
begin
|
12
13
|
require 'bugsnag'
|
13
14
|
|
14
|
-
api_key
|
15
|
+
api_key = ENV["BUGSNAG_API_KEY"]
|
15
16
|
releaseStage = ENV["BUGSNAG_RELEASE_STAGE"] || "production"
|
16
|
-
appVersion
|
17
|
-
revision
|
18
|
-
repository
|
19
|
-
branch
|
17
|
+
appVersion = ENV["BUGSNAG_APP_VERSION"]
|
18
|
+
revision = ENV["BUGSNAG_REVISION"]
|
19
|
+
repository = ENV["BUGSNAG_REPOSITORY"]
|
20
|
+
branch = ENV["BUGSNAG_BRANCH"]
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
# TODO: more reliable ways to infer this are needed
|
23
|
+
path = defined?(Rails.root) ? Rails.root : Pathname.pwd
|
24
|
+
initializer = path + 'config/initializers/bugsnag'
|
25
|
+
if File.exist?(initializer)
|
26
|
+
require initializer
|
27
|
+
else
|
28
|
+
yml_filename = path + 'config/bugsnag.yml'
|
25
29
|
config = YAML.load_file(yml_filename) if File.exists?(yml_filename)
|
26
30
|
Bugsnag.configure(config[releaseStage] ? config[releaseStage] : config) if config
|
27
31
|
end
|
@@ -65,7 +69,7 @@ namespace :bugsnag do
|
|
65
69
|
end
|
66
70
|
|
67
71
|
desc "Send a test exception to Bugsnag."
|
68
|
-
task :test_exception => :load do
|
72
|
+
task :test_exception => :load do
|
69
73
|
begin
|
70
74
|
raise RuntimeError.new("Bugsnag test exception")
|
71
75
|
rescue => e
|
@@ -80,7 +84,7 @@ namespace :bugsnag do
|
|
80
84
|
end
|
81
85
|
|
82
86
|
task :load do
|
83
|
-
begin
|
87
|
+
begin
|
84
88
|
Rake::Task["environment"].invoke
|
85
89
|
rescue
|
86
90
|
end
|
data/spec/helper_spec.rb
CHANGED
@@ -1,33 +1,33 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Bugsnag::Helpers do
|
4
|
-
it "
|
4
|
+
it "cleans up recursive hashes" do
|
5
5
|
a = {:a => {}}
|
6
6
|
a[:a][:b] = a
|
7
|
-
Bugsnag::Helpers.cleanup_obj(a).
|
7
|
+
expect(Bugsnag::Helpers.cleanup_obj(a)).to eq({:a => {:b => "[RECURSION]"}})
|
8
8
|
end
|
9
9
|
|
10
|
-
it "
|
10
|
+
it "cleans up recursive arrays" do
|
11
11
|
a = []
|
12
12
|
a << a
|
13
13
|
a << "hello"
|
14
|
-
Bugsnag::Helpers.cleanup_obj(a).
|
14
|
+
expect(Bugsnag::Helpers.cleanup_obj(a)).to eq(["[RECURSION]", "hello"])
|
15
15
|
end
|
16
16
|
|
17
|
-
it "
|
17
|
+
it "allows multiple copies of the same string" do
|
18
18
|
a = {:name => "bugsnag"}
|
19
19
|
a[:second] = a[:name]
|
20
|
-
Bugsnag::Helpers.cleanup_obj(a).
|
20
|
+
expect(Bugsnag::Helpers.cleanup_obj(a)).to eq({:name => "bugsnag", :second => "bugsnag"})
|
21
21
|
end
|
22
22
|
|
23
|
-
it "
|
23
|
+
it "allows multiple copies of the same object" do
|
24
24
|
a = []
|
25
25
|
b = ["hello"]
|
26
26
|
a << b; a << b
|
27
|
-
Bugsnag::Helpers.cleanup_obj(a).
|
27
|
+
expect(Bugsnag::Helpers.cleanup_obj(a)).to eq([["hello"], ["hello"]])
|
28
28
|
end
|
29
29
|
|
30
|
-
it "
|
30
|
+
it "reduces hash size correctly" do
|
31
31
|
meta_data = {
|
32
32
|
:key_one => "this should not be truncated",
|
33
33
|
:key_two => ""
|
@@ -35,56 +35,56 @@ describe Bugsnag::Helpers do
|
|
35
35
|
|
36
36
|
1000.times {|i| meta_data[:key_two] += "this should be truncated " }
|
37
37
|
|
38
|
-
meta_data[:key_two].length.
|
38
|
+
expect(meta_data[:key_two].length).to be > 4096
|
39
39
|
|
40
40
|
meta_data_return = Bugsnag::Helpers.reduce_hash_size meta_data
|
41
41
|
|
42
|
-
meta_data_return[:key_one].length.
|
43
|
-
meta_data_return[:key_one].
|
42
|
+
expect(meta_data_return[:key_one].length).to eq(28)
|
43
|
+
expect(meta_data_return[:key_one]).to eq("this should not be truncated")
|
44
44
|
|
45
|
-
meta_data_return[:key_two].length.
|
46
|
-
meta_data_return[:key_two].match(/\[TRUNCATED\]$/).nil
|
45
|
+
expect(meta_data_return[:key_two].length).to eq(4107)
|
46
|
+
expect(meta_data_return[:key_two].match(/\[TRUNCATED\]$/).nil?).to eq(false)
|
47
47
|
|
48
|
-
meta_data[:key_two].length.
|
49
|
-
meta_data[:key_two].match(/\[TRUNCATED\]$/).nil
|
48
|
+
expect(meta_data[:key_two].length).to be > 4096
|
49
|
+
expect(meta_data[:key_two].match(/\[TRUNCATED\]$/).nil?).to eq(true)
|
50
50
|
|
51
|
-
meta_data[:key_one].length.
|
52
|
-
meta_data[:key_one].
|
51
|
+
expect(meta_data[:key_one].length).to eq(28)
|
52
|
+
expect(meta_data[:key_one]).to eq("this should not be truncated")
|
53
53
|
end
|
54
54
|
|
55
|
-
it "
|
55
|
+
it "works with no filters configured" do
|
56
56
|
url = Bugsnag::Helpers.cleanup_url "/dir/page?param1=value1¶m2=value2"
|
57
57
|
|
58
|
-
url.
|
58
|
+
expect(url).to eq("/dir/page?param1=value1¶m2=value2")
|
59
59
|
end
|
60
60
|
|
61
|
-
it "
|
61
|
+
it "does not filter with no get params" do
|
62
62
|
url = Bugsnag::Helpers.cleanup_url "/dir/page"
|
63
63
|
|
64
|
-
url.
|
64
|
+
expect(url).to eq("/dir/page")
|
65
65
|
end
|
66
66
|
|
67
|
-
it "
|
67
|
+
it "leaves a url alone if no filters match" do
|
68
68
|
url = Bugsnag::Helpers.cleanup_url "/dir/page?param1=value1¶m2=value2", ["param3"]
|
69
69
|
|
70
|
-
url.
|
70
|
+
expect(url).to eq("/dir/page?param1=value1¶m2=value2")
|
71
71
|
end
|
72
72
|
|
73
|
-
it "
|
73
|
+
it "filters a single get param" do
|
74
74
|
url = Bugsnag::Helpers.cleanup_url "/dir/page?param1=value1¶m2=value2", ["param1"]
|
75
75
|
|
76
|
-
url.
|
76
|
+
expect(url).to eq("/dir/page?param1=[FILTERED]¶m2=value2")
|
77
77
|
end
|
78
78
|
|
79
|
-
it "
|
79
|
+
it "filters a get param that contains a filtered term" do
|
80
80
|
url = Bugsnag::Helpers.cleanup_url '/dir/page?param1=value1¶m2=value2&bla=yes', ["param"]
|
81
81
|
|
82
|
-
url.
|
82
|
+
expect(url).to eq("/dir/page?param1=[FILTERED]¶m2=[FILTERED]&bla=yes")
|
83
83
|
end
|
84
84
|
|
85
|
-
it "
|
85
|
+
it "filters multiple matches" do
|
86
86
|
url = Bugsnag::Helpers.cleanup_url "/dir/page?param1=value1¶m2=value2¶m3=value3", ["param1", "param2"]
|
87
87
|
|
88
|
-
url.
|
88
|
+
expect(url).to eq("/dir/page?param1=[FILTERED]¶m2=[FILTERED]¶m3=value3")
|
89
89
|
end
|
90
90
|
end
|
data/spec/middleware_spec.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Bugsnag::MiddlewareStack do
|
4
|
-
it "
|
5
|
-
Bugsnag::Notification.
|
4
|
+
it "runs before_bugsnag_notify callbacks, adding a tab" do
|
5
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
6
6
|
event = get_event_from_payload(payload)
|
7
|
-
event[:metaData][:some_tab].
|
8
|
-
event[:metaData][:some_tab][:info].
|
9
|
-
event[:metaData][:some_tab][:data].
|
7
|
+
expect(event[:metaData][:some_tab]).not_to be_nil
|
8
|
+
expect(event[:metaData][:some_tab][:info]).to eq("here")
|
9
|
+
expect(event[:metaData][:some_tab][:data]).to eq("also here")
|
10
10
|
end
|
11
11
|
|
12
12
|
callback_run_count = 0
|
@@ -19,15 +19,15 @@ describe Bugsnag::MiddlewareStack do
|
|
19
19
|
}
|
20
20
|
|
21
21
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
22
|
-
callback_run_count.
|
22
|
+
expect(callback_run_count).to eq(1)
|
23
23
|
end
|
24
24
|
|
25
|
-
it "
|
26
|
-
Bugsnag::Notification.
|
25
|
+
it "runs before_bugsnag_notify callbacks, adding custom data" do
|
26
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
27
27
|
event = get_event_from_payload(payload)
|
28
|
-
event[:metaData][:custom].
|
29
|
-
event[:metaData][:custom][:info].
|
30
|
-
event[:metaData][:custom][:data].
|
28
|
+
expect(event[:metaData][:custom]).not_to be_nil
|
29
|
+
expect(event[:metaData][:custom][:info]).to eq("here")
|
30
|
+
expect(event[:metaData][:custom][:data]).to eq("also here")
|
31
31
|
end
|
32
32
|
|
33
33
|
callback_run_count = 0
|
@@ -39,17 +39,17 @@ describe Bugsnag::MiddlewareStack do
|
|
39
39
|
}
|
40
40
|
|
41
41
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
42
|
-
callback_run_count.
|
42
|
+
expect(callback_run_count).to eq(1)
|
43
43
|
end
|
44
44
|
|
45
|
-
it "
|
46
|
-
Bugsnag::Notification.
|
45
|
+
it "runs before_bugsnag_notify callbacks, setting the user" do
|
46
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
47
47
|
event = get_event_from_payload(payload)
|
48
|
-
event[:user].
|
49
|
-
event[:user][:id].
|
50
|
-
event[:user][:email].
|
51
|
-
event[:user][:name].
|
52
|
-
event[:user][:random_key].
|
48
|
+
expect(event[:user]).not_to be_nil
|
49
|
+
expect(event[:user][:id]).to eq("here")
|
50
|
+
expect(event[:user][:email]).to eq("also here")
|
51
|
+
expect(event[:user][:name]).to eq("also here too")
|
52
|
+
expect(event[:user][:random_key]).to eq("also here too too")
|
53
53
|
end
|
54
54
|
|
55
55
|
callback_run_count = 0
|
@@ -59,15 +59,15 @@ describe Bugsnag::MiddlewareStack do
|
|
59
59
|
}
|
60
60
|
|
61
61
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
62
|
-
callback_run_count.
|
62
|
+
expect(callback_run_count).to eq(1)
|
63
63
|
end
|
64
64
|
|
65
|
-
it "overrides
|
66
|
-
Bugsnag::Notification.
|
65
|
+
it "overrides data set in before_notify" do
|
66
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
67
67
|
event = get_event_from_payload(payload)
|
68
|
-
event[:metaData][:custom].
|
69
|
-
event[:metaData][:custom][:info].
|
70
|
-
event[:metaData][:custom][:data].
|
68
|
+
expect(event[:metaData][:custom]).not_to be_nil
|
69
|
+
expect(event[:metaData][:custom][:info]).to eq("here2")
|
70
|
+
expect(event[:metaData][:custom][:data]).to eq("also here")
|
71
71
|
end
|
72
72
|
|
73
73
|
callback_run_count = 0
|
@@ -79,24 +79,22 @@ describe Bugsnag::MiddlewareStack do
|
|
79
79
|
}
|
80
80
|
|
81
81
|
Bugsnag.notify(BugsnagTestException.new("It crashed"), {:info => "here2"})
|
82
|
-
callback_run_count.
|
82
|
+
expect(callback_run_count).to eq(1)
|
83
83
|
end
|
84
84
|
|
85
|
-
it "
|
86
|
-
Bugsnag::Notification.
|
85
|
+
it "does not have have before or after callbacks by default" do
|
86
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload) do |endpoint, payload|
|
87
87
|
event = get_event_from_payload(payload)
|
88
|
-
event[:metaData].
|
88
|
+
expect(event[:metaData].size).to eq(0)
|
89
89
|
end
|
90
90
|
|
91
|
-
Bugsnag.before_notify_callbacks.
|
92
|
-
Bugsnag.after_notify_callbacks.
|
91
|
+
expect(Bugsnag.before_notify_callbacks.size).to eq(0)
|
92
|
+
expect(Bugsnag.after_notify_callbacks.size).to eq(0)
|
93
93
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
94
94
|
end
|
95
95
|
|
96
|
-
it "
|
97
|
-
Bugsnag::Notification.
|
98
|
-
event = get_event_from_payload(payload)
|
99
|
-
end
|
96
|
+
it "runs after_bugsnag_notify callbacks" do
|
97
|
+
expect(Bugsnag::Notification).to receive(:deliver_exception_payload)
|
100
98
|
|
101
99
|
callback_run_count = 0
|
102
100
|
Bugsnag.after_notify_callbacks << lambda {|notif|
|
@@ -105,10 +103,10 @@ describe Bugsnag::MiddlewareStack do
|
|
105
103
|
|
106
104
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
107
105
|
|
108
|
-
callback_run_count.
|
106
|
+
expect(callback_run_count).to eq(1)
|
109
107
|
end
|
110
108
|
|
111
|
-
it "
|
109
|
+
it "does not execute disabled bugsnag middleware" do
|
112
110
|
callback_run_count = 0
|
113
111
|
Bugsnag.configure do |config|
|
114
112
|
config.middleware.disable(Bugsnag::Middleware::Callbacks)
|
@@ -119,6 +117,6 @@ describe Bugsnag::MiddlewareStack do
|
|
119
117
|
}
|
120
118
|
|
121
119
|
Bugsnag.notify(BugsnagTestException.new("It crashed"))
|
122
|
-
callback_run_count.
|
120
|
+
expect(callback_run_count).to eq(0)
|
123
121
|
end
|
124
|
-
end
|
122
|
+
end
|