bugsnag 2.1.0 → 2.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0aeecfdb8779e10d102017b3c790a61a267ec9d5
4
- data.tar.gz: f25ba587cd16bbdae435b974af0cea1f304fb72f
3
+ metadata.gz: 9c3dbbe217f7c08fdabec9e5735794d768baada9
4
+ data.tar.gz: 4bbe9e4a0f85bb2b5a3ebf991cee121eb75d5020
5
5
  SHA512:
6
- metadata.gz: d94df43a04e198a7c59be2562653dd6725dcf0a1cd6a61eb4ffb3941edc7c1cb73991af7c849c993ca4fb951e205f1891c8d299fedcc36126304d76913cf5d52
7
- data.tar.gz: 680796ec69b78407e88ddd6de482dc6cd9f5a08f28bad3c9579be2f90a2529cf1355dd8aa6dc8956b5113ada3e5c50f4f8951818cfac9cc0257d7e154c412b94
6
+ metadata.gz: bcb11d2887710b46c363ec11d81952f04488ef1e4c9afb9236a6cad76a7509293ce53778e254cae9f694ab909ff8b2ae7c07d9066b7cc4e2ec8b800dd39c4d6b
7
+ data.tar.gz: 162cc3f3f3f8cacd55faa84fa20ebbe0a90d3214f0712460a26b54f7ef556b08479a450ee52335a6d5c521397552097c77979a9de0bb6d8f5d7c73df8f16af9f
data/.travis.yml CHANGED
@@ -1,18 +1,15 @@
1
1
  language: ruby
2
-
3
2
  rvm:
4
- - 2.1.0
5
- - 2.0.0
6
- - 1.9.3
7
- - jruby-18mode
8
- - jruby-19mode
9
- - 1.8.7
10
-
11
- # Workaround for broken bundler on travis CI - https://github.com/bundler/bundler/issues/2784
3
+ - 2.1.0
4
+ - 2.0.0
5
+ - 1.9.3
6
+ - jruby-18mode
7
+ - jruby-19mode
8
+ - 1.8.7
12
9
  before_install:
13
- - gem update --system 2.1.11
14
- - gem --version
15
-
10
+ - gem update --system 2.1.11
11
+ - gem --version
16
12
  notifications:
17
13
  hipchat:
18
- secure: "OLw2B1ggBDSeyJYgnZ2Ezf2fXbu5BHWSNFEJF38+TB4hYv+Wp3rElROhnyP6IttftLYz68Q8n9SjEUXTX9zXwTNt2fGBHIDwLnjt1uw7BrIOIHCUheOJdPheV2XxdJv9yem5MQ0vF+y33auLpyrA53b+nCbI5UsCXKISLe+C8ME="
14
+ rooms:
15
+ secure: cv5V8ivZExOywKL9n0CODnxy9m5u4rQ5ZMYK8XHPIoqQKkvH9DQOeb2ItW2aM2kxeupJEcQEy1Eu4sYMGhyzKUNdqbFtQBhDYxRwSAgTRIkGlHQCnznyExHWZbGfDB8y/m11HiZ1wuPuqs8ZZ+VccNb4bwJKbhPTbf1RZ+GPeU8=
data/CHANGELOG.md CHANGED
@@ -1,6 +1,10 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ 2.2.0
5
+ -----
6
+ - Move Bugsnag notifications onto a background thread.
7
+
4
8
  2.1.0
5
9
  -----
6
10
  - Add job detail support to delayed_job integration (thanks dtaniwaki!)
data/README.md CHANGED
@@ -17,7 +17,7 @@ Contents
17
17
 
18
18
  - [How to Install](#how-to-install)
19
19
  - [Sending Custom Data With Exceptions](#sending-custom-data-with-exceptions)
20
- - [Sending Non-Fatal Exceptions](#sending-non-fatal-exceptions)
20
+ - [Sending Handled Exceptions](#sending-handled-exceptions)
21
21
  - [Configuration](#configuration)
22
22
  - [Bugsnag Middleware](#bugsnag-middleware)
23
23
  - [Deploy Tracking](#deploy-tracking)
@@ -64,6 +64,15 @@ How to Install
64
64
  use Bugsnag::Rack
65
65
  ```
66
66
 
67
+ **Sinatra**: Note that `raise_errors` must be enabled. If you are using custom
68
+ error handlers, then you will need to notify Bugsnag explicitly:
69
+
70
+ ```ruby
71
+ error 500 do
72
+ Bugsnag.auto_notify($!)
73
+ erb :"errors/500"
74
+ end
75
+ ```
67
76
 
68
77
  Sending Custom Data With Exceptions
69
78
  -----------------------------------
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.1.0
1
+ 2.2.0
@@ -14,7 +14,6 @@ module Bugsnag
14
14
  attr_accessor :app_version
15
15
  attr_accessor :app_type
16
16
  attr_accessor :params_filters
17
- attr_accessor :ignore_classes
18
17
  attr_accessor :ignore_user_agents
19
18
  attr_accessor :endpoint
20
19
  attr_accessor :logger
@@ -28,6 +27,8 @@ module Bugsnag
28
27
  attr_accessor :timeout
29
28
  attr_accessor :hostname
30
29
 
30
+ attr_writer :ignore_classes
31
+
31
32
  THREAD_LOCAL_NAME = "bugsnag_req_data"
32
33
 
33
34
  DEFAULT_ENDPOINT = "notify.bugsnag.com"
@@ -68,6 +69,11 @@ module Bugsnag
68
69
  self.middleware.use Bugsnag::Middleware::Callbacks
69
70
  end
70
71
 
72
+ # Accept both String and Class instances as an ignored class
73
+ def ignore_classes
74
+ @ignore_classes.map! { |klass| klass.is_a?(Class) ? klass.name : klass }
75
+ end
76
+
71
77
  def should_notify?
72
78
  @release_stage.nil? || @notify_release_stages.nil? || @notify_release_stages.include?(@release_stage)
73
79
  end
@@ -32,6 +32,8 @@ module Bugsnag
32
32
  attr_accessor :user
33
33
  attr_accessor :configuration
34
34
 
35
+ @queue = Bugsnag::Queue.new
36
+
35
37
  class << self
36
38
  def deliver_exception_payload(endpoint, payload)
37
39
  begin
@@ -44,8 +46,8 @@ module Bugsnag
44
46
  payload_string = Bugsnag::Helpers.dump_json(payload)
45
47
  end
46
48
 
47
- response = post(endpoint, {:body => payload_string})
48
- Bugsnag.debug("Notification to #{endpoint} finished, response was #{response.code}, payload was #{payload_string}")
49
+ do_post(endpoint, payload_string)
50
+
49
51
  rescue StandardError => e
50
52
  # KLUDGE: Since we don't re-raise http exceptions, this breaks rspec
51
53
  raise if e.class.to_s == "RSpec::Expectations::ExpectationNotMetError"
@@ -53,6 +55,19 @@ module Bugsnag
53
55
  Bugsnag.warn("Notification to #{endpoint} failed, #{e.inspect}")
54
56
  Bugsnag.warn(e.backtrace)
55
57
  end
58
+
59
+ end
60
+
61
+ def do_post(endpoint, payload_string)
62
+ @queue.push proc{
63
+ begin
64
+ response = post(endpoint, {:body => payload_string})
65
+ Bugsnag.debug("Notification to #{endpoint} finished, response was #{response.code}, payload was #{payload_string}")
66
+ rescue StandardError => e
67
+ Bugsnag.warn("Notification to #{endpoint} failed, #{e.inspect}")
68
+ Bugsnag.warn(e.backtrace)
69
+ end
70
+ }
56
71
  end
57
72
  end
58
73
 
@@ -270,8 +285,11 @@ module Bugsnag
270
285
 
271
286
  def ignore_exception_class?
272
287
  ex = @exceptions.last
288
+ ex_name = error_class(ex)
289
+ ancestor_chain = ex.class.ancestors.select { |ancestor| ancestor.is_a?(Class) }.map { |ancestor| error_class(ancestor) }.to_set
290
+
273
291
  @configuration.ignore_classes.any? do |to_ignore|
274
- to_ignore.is_a?(Proc) ? to_ignore.call(ex) : to_ignore == error_class(ex)
292
+ to_ignore.is_a?(Proc) ? to_ignore.call(ex) : ancestor_chain.include?(to_ignore)
275
293
  end
276
294
  end
277
295
 
@@ -0,0 +1,36 @@
1
+ require 'thread'
2
+
3
+ module Bugsnag
4
+ class Queue < ::Queue
5
+ MAX_OUTSTANDING_REQUESTS = 100
6
+ STOP = Object.new
7
+
8
+ def push(*)
9
+ if length > MAX_OUTSTANDING_REQUESTS
10
+ Bugsnag.warn("Dropping notification, #{length} outstanding requests")
11
+ return
12
+ end
13
+ @thread ||= create_processor
14
+ super
15
+ end
16
+
17
+ private
18
+
19
+ def create_processor
20
+ t = Thread.new do
21
+ while x = pop
22
+ break if x == STOP
23
+ x.call
24
+ end
25
+ end
26
+
27
+ at_exit do
28
+ Bugsnag.warn("Waiting for #{length} outstanding request(s)") unless empty?
29
+ push STOP
30
+ t.join
31
+ end
32
+
33
+ t
34
+ end
35
+ end
36
+ end
data/lib/bugsnag.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require "rubygems"
2
2
 
3
3
  require "bugsnag/version"
4
+ require "bugsnag/queue"
4
5
  require "bugsnag/configuration"
5
6
  require "bugsnag/meta_data"
6
7
  require "bugsnag/notification"
@@ -0,0 +1,33 @@
1
+ require 'webrick'
2
+ require 'spec_helper'
3
+
4
+ describe 'Bugsnag' do
5
+ server = nil
6
+ queue = Queue.new
7
+
8
+ before do
9
+ server = WEBrick::HTTPServer.new :Port => 0, :Logger => WEBrick::Log.new("/dev/null"), :AccessLog => []
10
+ server.mount_proc '/' do |req, res|
11
+ queue.push req.body
12
+ res.status = 200
13
+ res.body = "OK\n"
14
+ end
15
+ Thread.new{ server.start }
16
+ end
17
+ after do
18
+ server.stop
19
+ end
20
+
21
+ let(:request) { JSON.parse(queue.pop) }
22
+
23
+ it 'should send notifications over the wire' do
24
+ Bugsnag.configure do |config|
25
+ config.endpoint = "localhost:#{server.config[:Port]}"
26
+ config.use_ssl = false
27
+ end
28
+
29
+ Bugsnag.notify 'yo'
30
+
31
+ expect(request['events'][0]['exceptions'][0]['message']).to eq('yo')
32
+ end
33
+ end
@@ -6,6 +6,7 @@ require 'ostruct'
6
6
  module ActiveRecord; class RecordNotFound < RuntimeError; end; end
7
7
  class NestedException < StandardError; attr_accessor :original_exception; end
8
8
  class BugsnagTestExceptionWithMetaData < Exception; include Bugsnag::MetaData; end
9
+ class BugsnagSubclassTestException < BugsnagTestException; end
9
10
 
10
11
  class Ruby21Exception < RuntimeError
11
12
  attr_accessor :cause
@@ -251,10 +252,10 @@ describe Bugsnag::Notification do
251
252
  end
252
253
 
253
254
  it "truncates large meta_data before sending" do
254
- expect(Bugsnag::Notification).to receive(:post) do |endpoint, opts|
255
+ expect(Bugsnag::Notification).to receive(:do_post) do |endpoint, payload_string|
255
256
  # Truncated body should be no bigger than
256
257
  # 2 truncated hashes (4096*2) + rest of payload (5000)
257
- expect(opts[:body].length).to be < 4096*2 + 5000
258
+ expect(payload_string.length).to be < 4096*2 + 5000
258
259
  end
259
260
 
260
261
  Bugsnag.notify(BugsnagTestException.new("It crashed"), {
@@ -493,8 +494,16 @@ describe Bugsnag::Notification do
493
494
  Bugsnag.notify_or_ignore(BugsnagTestException.new("It crashed"))
494
495
  end
495
496
 
496
- it "does not notify if the exception is matched by an ignore_classes lambda function" do
497
- Bugsnag.configuration.ignore_classes << lambda {|e| e.message =~ /crashed/}
497
+ it "does not notify if exception's ancestor is an ignored class" do
498
+ Bugsnag.configuration.ignore_classes << "BugsnagTestException"
499
+
500
+ expect(Bugsnag::Notification).not_to receive(:deliver_exception_payload)
501
+
502
+ Bugsnag.notify_or_ignore(BugsnagSubclassTestException.new("It crashed"))
503
+ end
504
+
505
+ it "accepts both String and Class instances as an ignored class" do
506
+ Bugsnag.configuration.ignore_classes << BugsnagTestException
498
507
 
499
508
  expect(Bugsnag::Notification).not_to receive(:deliver_exception_payload)
500
509
 
@@ -693,8 +702,8 @@ describe Bugsnag::Notification do
693
702
  invalid_data = "fl\xc3ff"
694
703
  invalid_data.force_encoding('BINARY') if invalid_data.respond_to?(:force_encoding)
695
704
 
696
- expect(Bugsnag::Notification).to receive(:post) do |endpoint, opts|
697
- expect(opts[:body]).to match(/fl�ff/) if defined?(Encoding::UTF_8)
705
+ expect(Bugsnag::Notification).to receive(:do_post) do |endpoint, payload_string|
706
+ expect(payload_string).to match(/fl�ff/) if defined?(Encoding::UTF_8)
698
707
  end
699
708
 
700
709
  notify_test_exception(:fluff => {:fluff => invalid_data})
metadata CHANGED
@@ -1,103 +1,103 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bugsnag
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.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: 2014-06-26 00:00:00.000000000 Z
11
+ date: 2014-07-16 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: httparty
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - <
31
+ - - "<"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.0'
34
- - - '>='
34
+ - - ">="
35
35
  - !ruby/object:Gem::Version
36
36
  version: '0.6'
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
- - - <
41
+ - - "<"
42
42
  - !ruby/object:Gem::Version
43
43
  version: '1.0'
44
- - - '>='
44
+ - - ">="
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0.6'
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rake
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - '>='
51
+ - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0'
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - '>='
58
+ - - ">="
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: rspec
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - '>='
65
+ - - ">="
66
66
  - !ruby/object:Gem::Version
67
67
  version: '0'
68
68
  type: :development
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
- - - '>='
72
+ - - ">="
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0'
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: rdoc
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - '>='
79
+ - - ">="
80
80
  - !ruby/object:Gem::Version
81
81
  version: '0'
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
- - - '>='
86
+ - - ">="
87
87
  - !ruby/object:Gem::Version
88
88
  version: '0'
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: pry
91
91
  requirement: !ruby/object:Gem::Requirement
92
92
  requirements:
93
- - - '>='
93
+ - - ">="
94
94
  - !ruby/object:Gem::Version
95
95
  version: '0'
96
96
  type: :development
97
97
  prerelease: false
98
98
  version_requirements: !ruby/object:Gem::Requirement
99
99
  requirements:
100
- - - '>='
100
+ - - ">="
101
101
  - !ruby/object:Gem::Version
102
102
  version: '0'
103
103
  description: Ruby notifier for bugsnag.com
@@ -108,10 +108,10 @@ extra_rdoc_files:
108
108
  - LICENSE.txt
109
109
  - README.md
110
110
  files:
111
- - .document
112
- - .gitignore
113
- - .rspec
114
- - .travis.yml
111
+ - ".document"
112
+ - ".gitignore"
113
+ - ".rspec"
114
+ - ".travis.yml"
115
115
  - CHANGELOG.md
116
116
  - Gemfile
117
117
  - LICENSE.txt
@@ -136,6 +136,7 @@ files:
136
136
  - lib/bugsnag/middleware/warden_user.rb
137
137
  - lib/bugsnag/middleware_stack.rb
138
138
  - lib/bugsnag/notification.rb
139
+ - lib/bugsnag/queue.rb
139
140
  - lib/bugsnag/rack.rb
140
141
  - lib/bugsnag/rails.rb
141
142
  - lib/bugsnag/rails/action_controller_rescue.rb
@@ -152,6 +153,7 @@ files:
152
153
  - lib/generators/bugsnag/bugsnag_generator.rb
153
154
  - rails/init.rb
154
155
  - spec/helper_spec.rb
156
+ - spec/integration_spec.rb
155
157
  - spec/middleware_spec.rb
156
158
  - spec/notification_spec.rb
157
159
  - spec/rack_spec.rb
@@ -166,17 +168,17 @@ require_paths:
166
168
  - lib
167
169
  required_ruby_version: !ruby/object:Gem::Requirement
168
170
  requirements:
169
- - - '>='
171
+ - - ">="
170
172
  - !ruby/object:Gem::Version
171
173
  version: '0'
172
174
  required_rubygems_version: !ruby/object:Gem::Requirement
173
175
  requirements:
174
- - - '>='
176
+ - - ">="
175
177
  - !ruby/object:Gem::Version
176
178
  version: '0'
177
179
  requirements: []
178
180
  rubyforge_project:
179
- rubygems_version: 2.0.14
181
+ rubygems_version: 2.2.2
180
182
  signing_key:
181
183
  specification_version: 4
182
184
  summary: Ruby notifier for bugsnag.com