ratchetio 0.5.2 → 0.5.3

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.
data/.gitignore CHANGED
@@ -10,6 +10,7 @@ coverage
10
10
  doc/
11
11
  log/
12
12
  lib/bundler/man
13
+ vendor/bundle
13
14
  pkg
14
15
  rdoc
15
16
  spec/reports
data/.travis.yml CHANGED
@@ -13,3 +13,4 @@ rvm:
13
13
  matrix:
14
14
  allow_failures:
15
15
  - rvm: ruby-head
16
+ - rvm: rbx-18mode
data/CHANGELOG.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Change Log
2
2
 
3
+ **0.5.3**
4
+ - Add `Ratchetio.silenced`; which allows disabling reporting for a given block. See README for usage.
5
+
3
6
  **0.5.2**
4
7
  - Fix compat issue with delayed_job below version 3. Exceptions raised by delayed_job below version 3 will not be automatically caught; upgrade to v3 or catch and report by hand.
5
8
 
data/README.md CHANGED
@@ -94,6 +94,16 @@ By default, all exceptions reported through `Ratchetio.report_exception()` are r
94
94
  If you'd like to customize this list, see the example code in `config/initializers/ratchetio.rb`. Supported levels: "critical", "error", "warning", "info", "debug", "ignore". Set to "ignore" to cause the exception not to be reported at all.
95
95
 
96
96
 
97
+ ## Silencing exceptions at runtime
98
+
99
+ If you just want to disable exception reporting for a single block, use `Ratchetio.silenced`:
100
+
101
+ ```ruby
102
+ Ratchetio.silenced {
103
+ foo = bar # will not be reported
104
+ }
105
+ ```
106
+
97
107
 
98
108
  ## Asynchronous reporting
99
109
 
data/THANKS CHANGED
@@ -1,5 +1,6 @@
1
1
  Huge thanks to the following contributors (by github username). For the most up-to-date list, see https://github.com/ratchetio/ratchetio-gem/graphs/contributors
2
2
 
3
+ arr-ee
3
4
  kavu
4
5
  mipearson
5
6
  trisweb
@@ -1,3 +1,3 @@
1
1
  module Ratchetio
2
- VERSION = "0.5.2"
2
+ VERSION = "0.5.3"
3
3
  end
data/lib/ratchetio.rb CHANGED
@@ -15,9 +15,9 @@ require 'ratchetio/version'
15
15
  module Ratchetio
16
16
  class << self
17
17
  attr_writer :configuration
18
-
18
+
19
19
  # Configures the gem.
20
- #
20
+ #
21
21
  # Call on app startup to set the `access_token` (required) and other config params.
22
22
  # In a Rails app, this is called by `config/initializers/ratchetio.rb` which is generated
23
23
  # with `rails generate ratchetio access-token-here`
@@ -29,7 +29,7 @@ module Ratchetio
29
29
  def configure
30
30
  yield(configuration)
31
31
  end
32
-
32
+
33
33
  def reconfigure
34
34
  @configuration = Configuration.new
35
35
  yield(configuration)
@@ -52,7 +52,7 @@ module Ratchetio
52
52
  # end
53
53
  #
54
54
  # @param exception [Exception] The exception object to report
55
- # @param request_data [Hash] Data describing the request. Should be the result of calling
55
+ # @param request_data [Hash] Data describing the request. Should be the result of calling
56
56
  # `ratchetio_request_data`.
57
57
  # @param person_data [Hash] Data describing the affected person. Should be the result of calling
58
58
  # `ratchetio_person_data`
@@ -61,13 +61,11 @@ module Ratchetio
61
61
  return
62
62
  end
63
63
 
64
- filtered_level = configuration.exception_level_filters[exception.class.name]
65
- if filtered_level == 'ignore'
66
- # ignored - do nothing
64
+ if ignored?(exception)
67
65
  return
68
66
  end
69
67
 
70
- data = exception_data(exception, filtered_level)
68
+ data = exception_data(exception, filtered_level(exception))
71
69
  data[:request] = request_data if request_data
72
70
  data[:person] = person_data if person_data
73
71
 
@@ -84,17 +82,17 @@ module Ratchetio
84
82
  # @example
85
83
  # Ratchetio.report_message("User login failed", 'info', :user_id => 123)
86
84
  #
87
- # @param message [String] The message body. This will be used to identify the message within
88
- # Ratchet. For best results, avoid putting variables in the message body; pass them as
89
- # `extra_data` instead.
85
+ # @param message [String] The message body. This will be used to identify the message within
86
+ # Ratchet. For best results, avoid putting variables in the message body; pass them as
87
+ # `extra_data` instead.
90
88
  # @param level [String] The level. One of: 'critical', 'error', 'warning', 'info', 'debug'
91
- # @param extra_data [Hash] Additional data to include alongside the body. Don't use 'body' as
89
+ # @param extra_data [Hash] Additional data to include alongside the body. Don't use 'body' as
92
90
  # it is reserved.
93
91
  def report_message(message, level = 'info', extra_data = {})
94
92
  unless configuration.enabled
95
93
  return
96
94
  end
97
-
95
+
98
96
  data = message_data(message, level, extra_data)
99
97
  payload = build_payload(data)
100
98
  schedule_payload(payload)
@@ -102,6 +100,21 @@ module Ratchetio
102
100
  logger.error "[Ratchet.io] Error reporting message to Ratchet.io: #{e}"
103
101
  end
104
102
 
103
+ # Turns off reporting for the given block.
104
+ #
105
+ # @example
106
+ # Ratchetio.silenced { raise }
107
+ #
108
+ # @yield Block which exceptions won't be reported.
109
+ def silenced
110
+ begin
111
+ yield
112
+ rescue => e
113
+ e.instance_variable_set(:@_ratchet_do_not_report, true)
114
+ raise
115
+ end
116
+ end
117
+
105
118
  def process_payload(payload)
106
119
  begin
107
120
  if configuration.write_to_file
@@ -116,9 +129,25 @@ module Ratchetio
116
129
 
117
130
  private
118
131
 
132
+ def ignored?(exception)
133
+ if filtered_level(exception) == 'ignore'
134
+ return true
135
+ end
136
+
137
+ if exception.instance_variable_get(:@_ratchet_do_not_report)
138
+ return true
139
+ end
140
+
141
+ false
142
+ end
143
+
144
+ def filtered_level(exception)
145
+ configuration.exception_level_filters[exception.class.name]
146
+ end
147
+
119
148
  def message_data(message, level, extra_data)
120
149
  data = base_data(level)
121
-
150
+
122
151
  data[:body] = {
123
152
  :message => {
124
153
  :body => message.to_s
@@ -126,13 +155,13 @@ module Ratchetio
126
155
  }
127
156
  data[:body][:message].merge!(extra_data)
128
157
  data[:server] = server_data
129
-
158
+
130
159
  data
131
160
  end
132
161
 
133
162
  def exception_data(exception, force_level = nil)
134
163
  data = base_data
135
-
164
+
136
165
  data[:level] = force_level if force_level
137
166
 
138
167
  # parse backtrace
@@ -159,7 +188,7 @@ module Ratchetio
159
188
  }
160
189
 
161
190
  data[:server] = server_data
162
-
191
+
163
192
  data
164
193
  end
165
194
 
@@ -170,7 +199,7 @@ module Ratchetio
170
199
  end
171
200
  configuration.logger
172
201
  end
173
-
202
+
174
203
  def write_payload(payload)
175
204
  if configuration.use_async
176
205
  @file_semaphore.synchronize {
@@ -180,15 +209,15 @@ module Ratchetio
180
209
  do_write_payload(payload)
181
210
  end
182
211
  end
183
-
212
+
184
213
  def do_write_payload(payload)
185
214
  logger.info '[Ratchet.io] Writing payload to file'
186
-
215
+
187
216
  begin
188
217
  unless @file
189
218
  @file = File.open(configuration.filepath, "a")
190
219
  end
191
-
220
+
192
221
  @file.puts payload
193
222
  @file.flush
194
223
  logger.info "[Ratchet.io] Success"
@@ -196,13 +225,13 @@ module Ratchetio
196
225
  logger.error "[Ratchet.io] Error opening/writing to file: #{e}"
197
226
  end
198
227
  end
199
-
228
+
200
229
  def send_payload(payload)
201
230
  logger.info '[Ratchet.io] Sending payload'
202
-
231
+
203
232
  uri = URI.parse(configuration.endpoint)
204
233
  http = Net::HTTP.new(uri.host, uri.port)
205
-
234
+
206
235
  if uri.scheme == 'https'
207
236
  http.use_ssl = true
208
237
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
@@ -219,21 +248,21 @@ module Ratchetio
219
248
  logger.info "[Ratchet.io] Response: #{response.body}"
220
249
  end
221
250
  end
222
-
251
+
223
252
  def schedule_payload(payload)
224
253
  logger.info '[Ratchet.io] Scheduling payload'
225
-
254
+
226
255
  if configuration.use_async
227
256
  unless configuration.async_handler
228
257
  configuration.async_handler = method(:default_async_handler)
229
258
  end
230
-
259
+
231
260
  if configuration.write_to_file
232
261
  unless @file_semaphore
233
262
  @file_semaphore = Mutex.new
234
263
  end
235
264
  end
236
-
265
+
237
266
  configuration.async_handler.call(payload)
238
267
  else
239
268
  process_payload(payload)
@@ -261,26 +290,26 @@ module Ratchetio
261
290
  :version => VERSION
262
291
  }
263
292
  }
264
-
293
+
265
294
  if defined?(SecureRandom) and SecureRandom.respond_to?(:uuid)
266
295
  data[:uuid] = SecureRandom.uuid
267
296
  end
268
-
297
+
269
298
  data
270
299
  end
271
300
 
272
301
  def server_data
273
302
  config = configuration
274
-
303
+
275
304
  data = {
276
305
  :host => Socket.gethostname
277
306
  }
278
307
  data[:root] = config.root.to_s if config.root
279
308
  data[:branch] = config.branch if config.branch
280
-
309
+
281
310
  data
282
311
  end
283
-
312
+
284
313
  def default_async_handler(payload)
285
314
  if defined?(GirlFriday)
286
315
  unless @queue
@@ -288,7 +317,7 @@ module Ratchetio
288
317
  process_payload(payload)
289
318
  end
290
319
  end
291
-
320
+
292
321
  @queue.push(payload)
293
322
  else
294
323
  logger.warn '[Ratchet.io] girl_friday not found to handle async call, falling back to Thread'
@@ -3,7 +3,7 @@ class HomeController < ApplicationController
3
3
  @users = User.all
4
4
 
5
5
  Ratchetio.report_message("Test message from controller with no data", "debug")
6
- Ratchetio.report_message("Test message from controller with extra data", "debug",
6
+ Ratchetio.report_message("Test message from controller with extra data", "debug",
7
7
  :foo => "bar", :num_users => @users.length)
8
8
  end
9
9
 
@@ -10,14 +10,14 @@ describe Ratchetio do
10
10
  Ratchetio.configure do |config|
11
11
  config.logger = logger_mock
12
12
  end
13
-
13
+
14
14
  begin
15
15
  foo = bar
16
16
  rescue => e
17
17
  @exception = e
18
18
  end
19
19
  end
20
-
20
+
21
21
  let(:logger_mock) { double("Rails.logger").as_null_object }
22
22
 
23
23
  it 'should report exceptions without person or request data' do
@@ -30,9 +30,9 @@ describe Ratchetio do
30
30
  Ratchetio.configure do |config|
31
31
  config.enabled = false
32
32
  end
33
-
33
+
34
34
  Ratchetio.report_exception(@exception)
35
-
35
+
36
36
  Ratchetio.configure do |config|
37
37
  config.enabled = true
38
38
  end
@@ -66,14 +66,30 @@ describe Ratchetio do
66
66
  logger_mock.should_not_receive(:info)
67
67
  logger_mock.should_not_receive(:warn)
68
68
  logger_mock.should_not_receive(:error)
69
-
69
+
70
70
  Ratchetio.report_exception(@exception)
71
-
71
+
72
72
  Ratchetio.configure do |config|
73
73
  config.exception_level_filters = saved_filters
74
74
  end
75
75
  end
76
76
 
77
+ it 'should not report exceptions when silenced' do
78
+ Ratchetio.should_not_receive :schedule_payload
79
+
80
+ begin
81
+ test_var = 1
82
+ Ratchetio.silenced do
83
+ test_var = 2
84
+ raise
85
+ end
86
+ rescue => e
87
+ Ratchetio.report_exception(e)
88
+ end
89
+
90
+ test_var.should == 2
91
+ end
92
+
77
93
  it 'should report exception objects with no backtrace' do
78
94
  payload = nil
79
95
  Ratchetio.stub(:schedule_payload) do |*args|
@@ -93,7 +109,7 @@ describe Ratchetio do
93
109
  end
94
110
  end
95
111
  end
96
-
112
+
97
113
  context 'report_message' do
98
114
  before(:each) do
99
115
  configure
@@ -101,7 +117,7 @@ describe Ratchetio do
101
117
  config.logger = logger_mock
102
118
  end
103
119
  end
104
-
120
+
105
121
  let(:logger_mock) { double("Rails.logger").as_null_object }
106
122
 
107
123
  it 'should report simple messages' do
@@ -115,9 +131,9 @@ describe Ratchetio do
115
131
  Ratchetio.configure do |config|
116
132
  config.enabled = false
117
133
  end
118
-
134
+
119
135
  Ratchetio.report_message("Test message that should be ignored")
120
-
136
+
121
137
  Ratchetio.configure do |config|
122
138
  config.enabled = true
123
139
  end
@@ -145,7 +161,7 @@ describe Ratchetio do
145
161
  end
146
162
  end
147
163
  end
148
-
164
+
149
165
  context 'payload_destination' do
150
166
  before(:each) do
151
167
  configure
@@ -153,83 +169,84 @@ describe Ratchetio do
153
169
  config.logger = logger_mock
154
170
  config.filepath = 'test.ratchet'
155
171
  end
156
-
172
+
157
173
  begin
158
174
  foo = bar
159
175
  rescue => e
160
176
  @exception = e
161
177
  end
162
178
  end
163
-
179
+
164
180
  let(:logger_mock) { double("Rails.logger").as_null_object }
165
-
181
+
166
182
  it 'should send the payload over the network by default' do
167
183
  logger_mock.should_not_receive(:info).with('[Ratchet.io] Writing payload to file')
168
184
  logger_mock.should_receive(:info).with('[Ratchet.io] Sending payload')
169
185
  logger_mock.should_receive(:info).with('[Ratchet.io] Success')
170
186
  Ratchetio.report_exception(@exception)
171
187
  end
172
-
188
+
173
189
  it 'should save the payload to a file if set' do
174
190
  logger_mock.should_not_receive(:info).with('[Ratchet.io] Sending payload')
175
191
  logger_mock.should_receive(:info).with('[Ratchet.io] Writing payload to file')
176
192
  logger_mock.should_receive(:info).with('[Ratchet.io] Success')
177
-
193
+
178
194
  filepath = ''
179
-
195
+
180
196
  Ratchetio.configure do |config|
181
197
  config.write_to_file = true
182
198
  filepath = config.filepath
183
199
  end
184
-
200
+
185
201
  Ratchetio.report_exception(@exception)
186
-
202
+
187
203
  File.exist?(filepath).should == true
188
204
  File.read(filepath).should include test_access_token
189
205
  File.delete(filepath)
190
-
206
+
191
207
  Ratchetio.configure do |config|
192
208
  config.write_to_file = false
193
209
  end
194
210
  end
195
211
  end
196
-
212
+
197
213
  context 'asynchronous_handling' do
198
214
  before(:each) do
199
215
  configure
200
216
  Ratchetio.configure do |config|
201
217
  config.logger = logger_mock
202
218
  end
203
-
219
+
204
220
  begin
205
221
  foo = bar
206
222
  rescue => e
207
223
  @exception = e
208
224
  end
209
225
  end
210
-
226
+
211
227
  let(:logger_mock) { double("Rails.logger").as_null_object }
212
-
228
+
213
229
  it 'should send the payload using the default asynchronous handler girl_friday' do
214
230
  logger_mock.should_receive(:info).with('[Ratchet.io] Success')
215
-
231
+
216
232
  Ratchetio.configure do |config|
217
233
  config.use_async = true
218
234
  GirlFriday::WorkQueue::immediate!
219
235
  end
220
-
236
+
221
237
  Ratchetio.report_exception(@exception)
222
-
238
+
223
239
  Ratchetio.configure do |config|
224
240
  config.use_async = false
225
241
  GirlFriday::WorkQueue::queue!
226
242
  end
227
243
  end
228
-
244
+
229
245
  it 'should send the payload using a user-supplied asynchronous handler' do
230
246
  logger_mock.should_receive(:info).with('Custom async handler called')
247
+ logger_mock.should_receive(:info).with('[Ratchet.io] Sending payload')
231
248
  logger_mock.should_receive(:info).with('[Ratchet.io] Success')
232
-
249
+
233
250
  Ratchetio.configure do |config|
234
251
  config.use_async = true
235
252
  config.async_handler = Proc.new { |payload|
@@ -237,9 +254,9 @@ describe Ratchetio do
237
254
  Ratchetio.process_payload(payload)
238
255
  }
239
256
  end
240
-
257
+
241
258
  Ratchetio.report_exception(@exception)
242
-
259
+
243
260
  Ratchetio.configure do |config|
244
261
  config.use_async = false
245
262
  config.async_handler = Ratchetio.method(:default_async_handler)
@@ -264,16 +281,16 @@ describe Ratchetio do
264
281
  user_id = 123
265
282
  name = "Tester"
266
283
 
267
- data = Ratchetio.send(:message_data, @message_body, 'info',
284
+ data = Ratchetio.send(:message_data, @message_body, 'info',
268
285
  :user_id => user_id, :name => name)
269
-
286
+
270
287
  message = data[:body][:message]
271
288
  message[:body].should == @message_body
272
289
  message[:user_id].should == user_id
273
290
  message[:name].should == name
274
291
  end
275
292
  end
276
-
293
+
277
294
  context 'exception_data' do
278
295
  before(:each) do
279
296
  configure
@@ -283,7 +300,7 @@ describe Ratchetio do
283
300
  @exception = e
284
301
  end
285
302
  end
286
-
303
+
287
304
  it 'should accept force_level' do
288
305
  level = 'critical'
289
306
  data = Ratchetio.send(:exception_data, @exception, level)
@@ -292,11 +309,11 @@ describe Ratchetio do
292
309
 
293
310
  it 'should build valid exception data' do
294
311
  data = Ratchetio.send(:exception_data, @exception)
295
-
312
+
296
313
  data[:level].should_not be_nil
297
-
314
+
298
315
  trace = data[:body][:trace]
299
-
316
+
300
317
  frames = trace[:frames]
301
318
  frames.should be_a_kind_of(Array)
302
319
  frames.each do |frame|
@@ -306,14 +323,14 @@ describe Ratchetio do
306
323
  frame[:method].should be_a_kind_of(String)
307
324
  end
308
325
  end
309
-
326
+
310
327
  # should be NameError, but can be NoMethodError sometimes on rubinius 1.8
311
328
  # http://yehudakatz.com/2010/01/02/the-craziest-fing-bug-ive-ever-seen/
312
329
  trace[:exception][:class].should match(/^(NameError|NoMethodError)$/)
313
330
  trace[:exception][:message].should match(/^(undefined local variable or method `bar'|undefined method `bar' on an instance of)/)
314
331
  end
315
332
  end
316
-
333
+
317
334
  context 'logger' do
318
335
  before(:each) do
319
336
  reset_configuration
@@ -340,7 +357,7 @@ describe Ratchetio do
340
357
  reset_configuration
341
358
  end
342
359
  end
343
-
360
+
344
361
  context 'build_payload' do
345
362
  it 'should build valid json' do
346
363
  json = Ratchetio.send(:build_payload, {:foo => {:bar => "baz"}})
@@ -357,7 +374,7 @@ describe Ratchetio do
357
374
  it 'should have the correct notifier name' do
358
375
  Ratchetio.send(:base_data)[:notifier][:name].should == 'ratchetio-gem'
359
376
  end
360
-
377
+
361
378
  it 'should have the correct notifier version' do
362
379
  Ratchetio.send(:base_data)[:notifier][:version].should == Ratchetio::VERSION
363
380
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ratchetio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: