exception_handling 0.2.0 → 1.0.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/.gitignore +1 -0
- data/Gemfile.lock +47 -2
- data/README.md +109 -0
- data/Rakefile +12 -4
- data/exception_handling.gemspec +23 -19
- data/lib/exception_handling/log_stub_error.rb +84 -0
- data/lib/{exception_handling_mailer.rb → exception_handling/mailer.rb} +1 -1
- data/lib/exception_handling/methods.rb +69 -0
- data/lib/exception_handling/testing.rb +65 -0
- data/lib/exception_handling/version.rb +1 -1
- data/lib/exception_handling.rb +127 -91
- data/test/test_helper.rb +55 -2
- data/test/unit/exception_handling/log_error_stub_test.rb +83 -0
- data/test/unit/exception_handling/mailer_test.rb +79 -0
- data/test/unit/exception_handling/methods_test.rb +59 -0
- data/test/unit/exception_handling_test.rb +717 -0
- data/views/exception_handling/mailer/exception_notification.html.erb +4 -1
- metadata +62 -13
- data/README +0 -1
- data/test/exception_handling_test.rb +0 -977
- data/test/mocha_patch.rb +0 -63
@@ -1,977 +0,0 @@
|
|
1
|
-
require './test/test_helper'
|
2
|
-
require 'minitest/autorun'
|
3
|
-
require 'exception_handling'
|
4
|
-
|
5
|
-
ExceptionHandling.email_environment = 'test'
|
6
|
-
ExceptionHandling.sender_address = 'server@example.com'
|
7
|
-
ExceptionHandling.exception_recipients = 'exceptions@example.com'
|
8
|
-
ExceptionHandling.server_name = 'server'
|
9
|
-
|
10
|
-
class ExceptionHandlingTest < ActiveSupport::TestCase
|
11
|
-
class LoggerStub
|
12
|
-
attr_accessor :logged
|
13
|
-
|
14
|
-
def initialize
|
15
|
-
clear
|
16
|
-
end
|
17
|
-
|
18
|
-
def info(message)
|
19
|
-
logged << message
|
20
|
-
end
|
21
|
-
|
22
|
-
def warn(message)
|
23
|
-
logged << message
|
24
|
-
end
|
25
|
-
|
26
|
-
def fatal(message)
|
27
|
-
logged << message
|
28
|
-
end
|
29
|
-
|
30
|
-
def clear
|
31
|
-
@logged = []
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
|
36
|
-
ExceptionHandling.logger = LoggerStub.new
|
37
|
-
|
38
|
-
def dont_stub_log_error
|
39
|
-
true
|
40
|
-
end
|
41
|
-
|
42
|
-
class TestController
|
43
|
-
class Request
|
44
|
-
attr_accessor :parameters, :protocol, :host, :request_uri, :env, :session_options
|
45
|
-
def initialize
|
46
|
-
@parameters = {:id => "1"}
|
47
|
-
@protocol = 'http'
|
48
|
-
@host = 'localhost'
|
49
|
-
@request_uri = "/fun/testing.html?foo=bar"
|
50
|
-
@env = {:HOST => "local"}
|
51
|
-
@session_options = { :id => '93951506217301' }
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
attr_accessor :request, :session
|
56
|
-
class << self
|
57
|
-
attr_accessor :around_filter_method
|
58
|
-
end
|
59
|
-
|
60
|
-
def initialize
|
61
|
-
@request = Request.new
|
62
|
-
@session_id = "ZKL95"
|
63
|
-
@session =
|
64
|
-
if defined?(Username)
|
65
|
-
{
|
66
|
-
:login_count => 22,
|
67
|
-
:username_id => Username.first.id,
|
68
|
-
:user_id => User.first.id,
|
69
|
-
}
|
70
|
-
else
|
71
|
-
{ }
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def simulate_around_filter( &block )
|
76
|
-
set_current_controller( &block )
|
77
|
-
end
|
78
|
-
|
79
|
-
def controller_name
|
80
|
-
"TestController"
|
81
|
-
end
|
82
|
-
|
83
|
-
def action_name
|
84
|
-
"test_action"
|
85
|
-
end
|
86
|
-
|
87
|
-
def self.around_filter( method )
|
88
|
-
TestController.around_filter_method = method
|
89
|
-
end
|
90
|
-
|
91
|
-
def complete_request_uri
|
92
|
-
"#{@request.protocol}#{@request.host}#{@request.request_uri}"
|
93
|
-
end
|
94
|
-
|
95
|
-
include ExceptionHandling::Methods
|
96
|
-
end
|
97
|
-
|
98
|
-
if defined?(Rails)
|
99
|
-
class TestAdvertiser < Advertiser
|
100
|
-
def test_log_error( ex, message=nil )
|
101
|
-
log_error(ex, message)
|
102
|
-
end
|
103
|
-
|
104
|
-
def test_ensure_escalation(summary)
|
105
|
-
ensure_escalation(summary) do
|
106
|
-
yield
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def test_log_warning( message )
|
111
|
-
log_warning(message)
|
112
|
-
end
|
113
|
-
|
114
|
-
def test_ensure_safe(message="",&blk)
|
115
|
-
ensure_safe(message,&blk)
|
116
|
-
end
|
117
|
-
|
118
|
-
def self.task_exception exception
|
119
|
-
@@task_exception = exception
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
module EventMachineStub
|
125
|
-
class << self
|
126
|
-
attr_accessor :block
|
127
|
-
|
128
|
-
def schedule(&block)
|
129
|
-
@block = block
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
class SmtpClientStub
|
135
|
-
class << self
|
136
|
-
attr_reader :block
|
137
|
-
attr_reader :last_method
|
138
|
-
|
139
|
-
def errback(&block)
|
140
|
-
@block = block
|
141
|
-
end
|
142
|
-
|
143
|
-
def send_hash
|
144
|
-
@send_hash ||= {}
|
145
|
-
end
|
146
|
-
|
147
|
-
def send(hash)
|
148
|
-
@last_method = :send
|
149
|
-
send_hash.clear
|
150
|
-
send_hash.merge!(hash)
|
151
|
-
self
|
152
|
-
end
|
153
|
-
|
154
|
-
def asend(hash)
|
155
|
-
send(hash)
|
156
|
-
@last_method = :asend
|
157
|
-
self
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
class SmtpClientErrbackStub < SmtpClientStub
|
163
|
-
end
|
164
|
-
|
165
|
-
context "Exception Handling" do
|
166
|
-
setup do
|
167
|
-
ExceptionHandling.send(:clear_exception_summary)
|
168
|
-
end
|
169
|
-
|
170
|
-
context "exception filter parsing and loading" do
|
171
|
-
should "happen without an error" do
|
172
|
-
File.stubs(:mtime).returns( incrementing_mtime )
|
173
|
-
exception_filters = ExceptionHandling.send( :exception_filters )
|
174
|
-
assert( exception_filters.is_a?( ExceptionHandling::ExceptionFilters ) )
|
175
|
-
assert_nothing_raised "Loading the exception filter should not raise" do
|
176
|
-
exception_filters.send :load_file
|
177
|
-
end
|
178
|
-
assert !exception_filters.filtered?( "Scott says unlikely to ever match" )
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
context "ExceptionHandling.ensure_safe" do
|
183
|
-
should "log an exception if an exception is raised." do
|
184
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /\(blah\):\n.*exception_handling_test\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
185
|
-
ExceptionHandling.ensure_safe { raise ArgumentError.new("blah") }
|
186
|
-
end
|
187
|
-
|
188
|
-
should "should not log an exception if an exception is not raised." do
|
189
|
-
ExceptionHandling.logger.expects(:fatal).never
|
190
|
-
ExceptionHandling.ensure_safe { ; }
|
191
|
-
end
|
192
|
-
|
193
|
-
should "return its value if used during an assignment" do
|
194
|
-
ExceptionHandling.logger.expects(:fatal).never
|
195
|
-
b = ExceptionHandling.ensure_safe { 5 }
|
196
|
-
assert_equal 5, b
|
197
|
-
end
|
198
|
-
|
199
|
-
should "return nil if an exception is raised during an assignment" do
|
200
|
-
ExceptionHandling.logger.expects(:fatal).returns(nil)
|
201
|
-
b = ExceptionHandling.ensure_safe { raise ArgumentError.new("blah") }
|
202
|
-
assert_equal nil, b
|
203
|
-
end
|
204
|
-
|
205
|
-
should "allow a message to be appended to the error when logged." do
|
206
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /mooo \(blah\):\n.*exception_handling_test\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
207
|
-
b = ExceptionHandling.ensure_safe("mooo") { raise ArgumentError.new("blah") }
|
208
|
-
assert_nil b
|
209
|
-
end
|
210
|
-
|
211
|
-
should "only rescue StandardError and descendents" do
|
212
|
-
assert_raise(Exception) { ExceptionHandling.ensure_safe("mooo") { raise Exception } }
|
213
|
-
|
214
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /mooo \(blah\):\n.*exception_handling_test\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
215
|
-
b = ExceptionHandling.ensure_safe("mooo") { raise StandardError.new("blah") }
|
216
|
-
assert_nil b
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
context "ExceptionHandling.ensure_completely_safe" do
|
221
|
-
should "log an exception if an exception is raised." do
|
222
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /\(blah\):\n.*exception_handling_test\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
223
|
-
ExceptionHandling.ensure_completely_safe { raise ArgumentError.new("blah") }
|
224
|
-
end
|
225
|
-
|
226
|
-
should "should not log an exception if an exception is not raised." do
|
227
|
-
ExceptionHandling.logger.expects(:fatal).never
|
228
|
-
ExceptionHandling.ensure_completely_safe { ; }
|
229
|
-
end
|
230
|
-
|
231
|
-
should "return its value if used during an assignment" do
|
232
|
-
ExceptionHandling.logger.expects(:fatal).never
|
233
|
-
b = ExceptionHandling.ensure_completely_safe { 5 }
|
234
|
-
assert_equal 5, b
|
235
|
-
end
|
236
|
-
|
237
|
-
should "return nil if an exception is raised during an assignment" do
|
238
|
-
ExceptionHandling.logger.expects(:fatal).returns(nil)
|
239
|
-
b = ExceptionHandling.ensure_completely_safe { raise ArgumentError.new("blah") }
|
240
|
-
assert_equal nil, b
|
241
|
-
end
|
242
|
-
|
243
|
-
should "allow a message to be appended to the error when logged." do
|
244
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /mooo \(blah\):\n.*exception_handling_test\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
245
|
-
b = ExceptionHandling.ensure_completely_safe("mooo") { raise ArgumentError.new("blah") }
|
246
|
-
assert_nil b
|
247
|
-
end
|
248
|
-
|
249
|
-
should "rescue any instance or child of Exception" do
|
250
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /\(blah\):\n.*exception_handling_test\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
251
|
-
ExceptionHandling::ensure_completely_safe { raise Exception.new("blah") }
|
252
|
-
end
|
253
|
-
|
254
|
-
should "not rescue the special exceptions that Ruby uses" do
|
255
|
-
[SystemExit, SystemStackError, NoMemoryError, SecurityError].each do |exception|
|
256
|
-
assert_raise exception do
|
257
|
-
ExceptionHandling.ensure_completely_safe do
|
258
|
-
raise exception.new
|
259
|
-
end
|
260
|
-
end
|
261
|
-
end
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
context "ExceptionHandling.ensure_escalation" do
|
266
|
-
should "log the exception as usual and send the proper email" do
|
267
|
-
assert_equal 0, ActionMailer::Base.deliveries.count
|
268
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /\(blah\):\n.*exception_handling_test\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
269
|
-
ExceptionHandling.ensure_escalation( "Favorite Feature") { raise ArgumentError.new("blah") }
|
270
|
-
assert_equal 2, ActionMailer::Base.deliveries.count
|
271
|
-
email = ActionMailer::Base.deliveries.last
|
272
|
-
assert_equal 'test Escalation: Favorite Feature', email.subject
|
273
|
-
assert_match 'ArgumentError: blah', email.body.to_s
|
274
|
-
assert_match ExceptionHandling.last_exception_timestamp.to_s, email.body.to_s
|
275
|
-
end
|
276
|
-
|
277
|
-
should "should not escalate if an exception is not raised." do
|
278
|
-
assert_equal 0, ActionMailer::Base.deliveries.count
|
279
|
-
ExceptionHandling.logger.expects(:fatal).never
|
280
|
-
ExceptionHandling.ensure_escalation('Ignored') { ; }
|
281
|
-
assert_equal 0, ActionMailer::Base.deliveries.count
|
282
|
-
end
|
283
|
-
|
284
|
-
should "log if the escalation email can not be sent" do
|
285
|
-
Mail::Message.any_instance.expects(:deliver).times(2).returns(nil).then.raises(RuntimeError.new "Delivery Error")
|
286
|
-
exception_count = 0
|
287
|
-
exception_regexs = [/first_test_exception/, /safe_email_deliver .*Delivery Error/]
|
288
|
-
|
289
|
-
$stderr.stubs(:puts)
|
290
|
-
ExceptionHandling.logger.expects(:fatal).times(2).with { |ex| ex =~ exception_regexs[exception_count] or raise "Unexpected [#{exception_count}]: #{ex.inspect}"; exception_count += 1; true }
|
291
|
-
ExceptionHandling.ensure_escalation("Not Used") { raise ArgumentError.new("first_test_exception") }
|
292
|
-
#assert_equal 0, ActionMailer::Base.deliveries.count
|
293
|
-
end
|
294
|
-
end
|
295
|
-
|
296
|
-
context "exception timestamp" do
|
297
|
-
setup do
|
298
|
-
Time.now_override = Time.parse( '1986-5-21 4:17 am UTC' )
|
299
|
-
end
|
300
|
-
|
301
|
-
should "include the timestamp when the exception is logged" do
|
302
|
-
ExceptionHandling.logger.expects(:fatal).with { |ex| ex =~ /\(Error:517033020\) ArgumentError mooo \(blah\):\n.*exception_handling_test\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
303
|
-
b = ExceptionHandling.ensure_safe("mooo") { raise ArgumentError.new("blah") }
|
304
|
-
assert_nil b
|
305
|
-
|
306
|
-
assert_equal 517033020, ExceptionHandling.last_exception_timestamp
|
307
|
-
|
308
|
-
assert_emails 1
|
309
|
-
assert_match /517033020/, ActionMailer::Base.deliveries[-1].body.to_s
|
310
|
-
end
|
311
|
-
end
|
312
|
-
|
313
|
-
if defined?(LogErrorStub)
|
314
|
-
context "while running tests" do
|
315
|
-
setup do
|
316
|
-
stub_log_error
|
317
|
-
end
|
318
|
-
|
319
|
-
should "raise an error when log_error and log_warning are called" do
|
320
|
-
begin
|
321
|
-
ExceptionHandling.log_error("Something happened")
|
322
|
-
flunk
|
323
|
-
rescue LogErrorStub::UnexpectedExceptionLogged => ex
|
324
|
-
assert ex.to_s.starts_with?("StandardError: Something happened"), ex.to_s
|
325
|
-
end
|
326
|
-
|
327
|
-
begin
|
328
|
-
class ::RaisedError < StandardError; end
|
329
|
-
raise ::RaisedError, "This should raise"
|
330
|
-
rescue => ex
|
331
|
-
begin
|
332
|
-
ExceptionHandling.log_error(ex)
|
333
|
-
rescue LogErrorStub::UnexpectedExceptionLogged => ex_inner
|
334
|
-
assert ex_inner.to_s.starts_with?("RaisedError: This should raise"), ex_inner.to_s
|
335
|
-
end
|
336
|
-
end
|
337
|
-
end
|
338
|
-
|
339
|
-
should "allow for the regex specification of an expected exception to be ignored" do
|
340
|
-
exception_pattern = /StandardError: This is a test error/
|
341
|
-
assert_nil exception_whitelist # test that exception expectations are cleared
|
342
|
-
expects_exception(exception_pattern)
|
343
|
-
assert_equal exception_pattern, exception_whitelist[0][0]
|
344
|
-
begin
|
345
|
-
ExceptionHandling.log_error("This is a test error")
|
346
|
-
rescue => ex
|
347
|
-
flunk # Shouldn't raise an error in this case
|
348
|
-
end
|
349
|
-
end
|
350
|
-
|
351
|
-
should "allow for the string specification of an expected exception to be ignored" do
|
352
|
-
exception_pattern = "StandardError: This is a test error"
|
353
|
-
assert_nil exception_whitelist # test that exception expectations are cleared
|
354
|
-
expects_exception(exception_pattern)
|
355
|
-
assert_equal exception_pattern, exception_whitelist[0][0]
|
356
|
-
begin
|
357
|
-
ExceptionHandling.log_error("This is a test error")
|
358
|
-
rescue => ex
|
359
|
-
flunk # Shouldn't raise an error in this case
|
360
|
-
end
|
361
|
-
end
|
362
|
-
|
363
|
-
should "allow multiple errors to be ignored" do
|
364
|
-
class IgnoredError < StandardError; end
|
365
|
-
assert_nil exception_whitelist # test that exception expectations are cleared
|
366
|
-
expects_exception /StandardError: This is a test error/
|
367
|
-
expects_exception /IgnoredError: This should be ignored/
|
368
|
-
ExceptionHandling.log_error("This is a test error")
|
369
|
-
begin
|
370
|
-
raise IgnoredError, "This should be ignored"
|
371
|
-
rescue IgnoredError => ex
|
372
|
-
ExceptionHandling.log_error(ex)
|
373
|
-
end
|
374
|
-
end
|
375
|
-
|
376
|
-
should "expect exception twice if declared twice" do
|
377
|
-
expects_exception /StandardError: ERROR: I love lamp/
|
378
|
-
expects_exception /StandardError: ERROR: I love lamp/
|
379
|
-
ExceptionHandling.log_error("ERROR: I love lamp")
|
380
|
-
ExceptionHandling.log_error("ERROR: I love lamp")
|
381
|
-
end
|
382
|
-
end
|
383
|
-
end
|
384
|
-
|
385
|
-
should "send just one copy of exceptions that don't repeat" do
|
386
|
-
ExceptionHandling.log_error(exception_1)
|
387
|
-
ExceptionHandling.log_error(exception_2)
|
388
|
-
assert_emails 2
|
389
|
-
assert_match /Exception 1/, ActionMailer::Base.deliveries[-2].subject
|
390
|
-
assert_match /Exception 2/, ActionMailer::Base.deliveries[-1].subject
|
391
|
-
end
|
392
|
-
|
393
|
-
should "only send 5 of a repeated error" do
|
394
|
-
assert_emails 5 do
|
395
|
-
10.times do
|
396
|
-
ExceptionHandling.log_error(exception_1)
|
397
|
-
end
|
398
|
-
end
|
399
|
-
end
|
400
|
-
|
401
|
-
should "only send 5 of a repeated error but don't send summary if 6th is different" do
|
402
|
-
assert_emails 5 do
|
403
|
-
5.times do
|
404
|
-
ExceptionHandling.log_error(exception_1)
|
405
|
-
end
|
406
|
-
end
|
407
|
-
assert_emails 1 do
|
408
|
-
ExceptionHandling.log_error(exception_2)
|
409
|
-
end
|
410
|
-
end
|
411
|
-
|
412
|
-
should "send the summary when the error is encountered an hour after the first occurrence" do
|
413
|
-
assert_emails 5 do # 5 exceptions, 4 summarized
|
414
|
-
9.times do |t|
|
415
|
-
ExceptionHandling.log_error(exception_1)
|
416
|
-
end
|
417
|
-
end
|
418
|
-
Time.now_override = 2.hours.from_now
|
419
|
-
assert_emails 1 do # 1 summary (4 + 1 = 5) after 2 hours
|
420
|
-
ExceptionHandling.log_error(exception_1)
|
421
|
-
end
|
422
|
-
assert_match /\[5 SUMMARIZED\]/, ActionMailer::Base.deliveries.last.subject
|
423
|
-
assert_match /This exception occurred 5 times since/, ActionMailer::Base.deliveries.last.body.to_s
|
424
|
-
|
425
|
-
assert_emails 0 do # still summarizing...
|
426
|
-
7.times do
|
427
|
-
ExceptionHandling.log_error(exception_1)
|
428
|
-
end
|
429
|
-
end
|
430
|
-
|
431
|
-
Time.now_override = 3.hours.from_now
|
432
|
-
|
433
|
-
assert_emails 1 + 2 do # 1 summary and 2 new
|
434
|
-
2.times do
|
435
|
-
ExceptionHandling.log_error(exception_2)
|
436
|
-
end
|
437
|
-
end
|
438
|
-
assert_match /\[7 SUMMARIZED\]/, ActionMailer::Base.deliveries[-3].subject
|
439
|
-
assert_match /This exception occurred 7 times since/, ActionMailer::Base.deliveries[-3].body.to_s
|
440
|
-
end
|
441
|
-
|
442
|
-
should "send the summary if a summary is available, but not sent when another exception comes up" do
|
443
|
-
assert_emails 5 do # 5 to start summarizing
|
444
|
-
6.times do
|
445
|
-
ExceptionHandling.log_error(exception_1)
|
446
|
-
end
|
447
|
-
end
|
448
|
-
|
449
|
-
assert_emails 1 + 1 do # 1 summary of previous, 1 from new exception
|
450
|
-
ExceptionHandling.log_error(exception_2)
|
451
|
-
end
|
452
|
-
|
453
|
-
assert_match /\[1 SUMMARIZED\]/, ActionMailer::Base.deliveries[-2].subject
|
454
|
-
assert_match /This exception occurred 1 times since/, ActionMailer::Base.deliveries[-2].body.to_s
|
455
|
-
|
456
|
-
assert_emails 5 do # 5 to start summarizing
|
457
|
-
10.times do
|
458
|
-
ExceptionHandling.log_error(exception_1)
|
459
|
-
end
|
460
|
-
end
|
461
|
-
|
462
|
-
assert_emails 0 do # still summarizing
|
463
|
-
11.times do
|
464
|
-
ExceptionHandling.log_error(exception_1)
|
465
|
-
end
|
466
|
-
end
|
467
|
-
end
|
468
|
-
|
469
|
-
class EventResponse
|
470
|
-
def to_s
|
471
|
-
"message from to_s!"
|
472
|
-
end
|
473
|
-
end
|
474
|
-
|
475
|
-
should "allow sections to have data with just a to_s method" do
|
476
|
-
ExceptionHandling.log_error("This is my RingSwitch example. Log, don't email!") do |data|
|
477
|
-
data.merge!(:event_response => EventResponse.new)
|
478
|
-
end
|
479
|
-
assert_emails 1
|
480
|
-
assert_match /message from to_s!/, ActionMailer::Base.deliveries.last.body.to_s
|
481
|
-
end
|
482
|
-
end
|
483
|
-
|
484
|
-
should "rescue exceptions that happen in log_error" do
|
485
|
-
ExceptionHandling.stubs(:make_exception).raises(ArgumentError.new("Bad argument"))
|
486
|
-
ExceptionHandling.expects(:write_exception_to_log).with do |ex, context, timestamp|
|
487
|
-
ex.to_s['Bad argument'] or raise "Unexpected ex #{ex.class} - #{ex}"
|
488
|
-
context['ExceptionHandling.log_error rescued exception while logging Runtime message'] or raise "Unexpected context #{context}"
|
489
|
-
true
|
490
|
-
end
|
491
|
-
$stderr.stubs(:puts)
|
492
|
-
ExceptionHandling.log_error(RuntimeError.new("A runtime error"), "Runtime message")
|
493
|
-
end
|
494
|
-
|
495
|
-
should "rescue exceptions that happen when log_error yields" do
|
496
|
-
ExceptionHandling.expects(:write_exception_to_log).with do |ex, context, timestamp|
|
497
|
-
ex.to_s['Bad argument'] or raise "=================================================\nUnexpected ex #{ex.class} - #{ex}\n#{ex.backtrace.join("\n")}\n=============================================\n"
|
498
|
-
context['Context message'] or raise "Unexpected context #{context}"
|
499
|
-
true
|
500
|
-
end
|
501
|
-
ExceptionHandling.log_error(ArgumentError.new("Bad argument"), "Context message") { |data| raise 'Error!!!' }
|
502
|
-
end
|
503
|
-
|
504
|
-
context "Exception Filtering" do
|
505
|
-
setup do
|
506
|
-
filter_list = { :exception1 => { :error => "my error message" },
|
507
|
-
:exception2 => { :error => "some other message", :session => "misc data" } }
|
508
|
-
YAML.stubs(:load_file).returns( ActiveSupport::HashWithIndifferentAccess.new( filter_list ) )
|
509
|
-
|
510
|
-
# bump modified time up to get the above filter loaded
|
511
|
-
File.stubs(:mtime).returns( incrementing_mtime )
|
512
|
-
end
|
513
|
-
|
514
|
-
should "handle case where filter list is not found" do
|
515
|
-
YAML.stubs(:load_file).raises( Errno::ENOENT.new( "File not found" ) )
|
516
|
-
|
517
|
-
ExceptionHandling.log_error( "My error message is in list" )
|
518
|
-
assert_emails 1
|
519
|
-
end
|
520
|
-
|
521
|
-
should "log exception and suppress email when exception is on filter list" do
|
522
|
-
ExceptionHandling.log_error( "Error message is not in list" )
|
523
|
-
assert_emails 1
|
524
|
-
|
525
|
-
ActionMailer::Base.deliveries.clear
|
526
|
-
ExceptionHandling.log_error( "My error message is in list" )
|
527
|
-
assert_emails 0
|
528
|
-
end
|
529
|
-
|
530
|
-
should "allow filtering exception on any text in exception data" do
|
531
|
-
filters = { :exception1 => { :session => "^data: my extra session data" } }
|
532
|
-
YAML.stubs(:load_file).returns( ActiveSupport::HashWithIndifferentAccess.new( filters ) )
|
533
|
-
|
534
|
-
ActionMailer::Base.deliveries.clear
|
535
|
-
ExceptionHandling.log_error( "No match here" ) do |data|
|
536
|
-
data[:session] = {
|
537
|
-
:key => "@session_id",
|
538
|
-
:data => "my extra session data"
|
539
|
-
}
|
540
|
-
end
|
541
|
-
assert_emails 0
|
542
|
-
|
543
|
-
ActionMailer::Base.deliveries.clear
|
544
|
-
ExceptionHandling.log_error( "No match here" ) do |data|
|
545
|
-
data[:session] = {
|
546
|
-
:key => "@session_id",
|
547
|
-
:data => "my extra session <no match!> data"
|
548
|
-
}
|
549
|
-
end
|
550
|
-
assert_emails 1, ActionMailer::Base.deliveries.map { |m| m.body.inspect }
|
551
|
-
end
|
552
|
-
|
553
|
-
should "reload filter list on the next exception if file was modified" do
|
554
|
-
ExceptionHandling.log_error( "Error message is not in list" )
|
555
|
-
assert_emails 1
|
556
|
-
|
557
|
-
filter_list = { :exception1 => { :error => "Error message is not in list" } }
|
558
|
-
YAML.stubs(:load_file).returns( ActiveSupport::HashWithIndifferentAccess.new( filter_list ) )
|
559
|
-
File.stubs(:mtime).returns( incrementing_mtime )
|
560
|
-
|
561
|
-
ActionMailer::Base.deliveries.clear
|
562
|
-
ExceptionHandling.log_error( "Error message is not in list" )
|
563
|
-
assert_emails 0, ActionMailer::Base.deliveries.map { |m| m.body.inspect }
|
564
|
-
end
|
565
|
-
|
566
|
-
should "not consider filter if both error message and body do not match" do
|
567
|
-
# error message matches, but not full text
|
568
|
-
ExceptionHandling.log_error( "some other message" )
|
569
|
-
assert_emails 1, ActionMailer::Base.deliveries.map { |m| m.body.inspect }
|
570
|
-
|
571
|
-
# now both match
|
572
|
-
ActionMailer::Base.deliveries.clear
|
573
|
-
ExceptionHandling.log_error( "some other message" ) do |data|
|
574
|
-
data[:session] = {:some_random_key => "misc data"}
|
575
|
-
end
|
576
|
-
assert_emails 0, ActionMailer::Base.deliveries.map { |m| m.body.inspect }
|
577
|
-
end
|
578
|
-
|
579
|
-
should "skip environment keys not on whitelist" do
|
580
|
-
ExceptionHandling.log_error( "some message" ) do |data|
|
581
|
-
data[:environment] = { :SERVER_PROTOCOL => "HTTP/1.0", :RAILS_SECRETS_YML_CONTENTS => 'password: VERY_SECRET_PASSWORD' }
|
582
|
-
end
|
583
|
-
assert_emails 1, ActionMailer::Base.deliveries.map { |m| m.body.inspect }
|
584
|
-
mail = ActionMailer::Base.deliveries.last
|
585
|
-
assert_nil mail.body.to_s["RAILS_SECRETS_YML_CONTENTS"], mail.body.to_s # this is not on whitelist
|
586
|
-
assert mail.body.to_s["SERVER_PROTOCOL: HTTP/1.0" ], mail.body.to_s # this is
|
587
|
-
end
|
588
|
-
|
589
|
-
should "omit environment defaults" do
|
590
|
-
ExceptionHandling.log_error( "some message" ) do |data|
|
591
|
-
data[:environment] = {:SERVER_PORT => '80', :SERVER_PROTOCOL => "HTTP/1.0"}
|
592
|
-
end
|
593
|
-
assert_emails 1, ActionMailer::Base.deliveries.map { |m| m.body.inspect }
|
594
|
-
mail = ActionMailer::Base.deliveries.last
|
595
|
-
assert_nil mail.body.to_s["SERVER_PORT" ], mail.body.to_s # this was default
|
596
|
-
assert mail.body.to_s["SERVER_PROTOCOL: HTTP/1.0"], mail.body.to_s # this was not
|
597
|
-
end
|
598
|
-
|
599
|
-
should "reject the filter file if any contain all empty regexes" do
|
600
|
-
filter_list = { :exception1 => { :error => "", :session => "" },
|
601
|
-
:exception2 => { :error => "is not in list", :session => "" } }
|
602
|
-
YAML.stubs(:load_file).returns( ActiveSupport::HashWithIndifferentAccess.new( filter_list ) )
|
603
|
-
File.stubs(:mtime).returns( incrementing_mtime )
|
604
|
-
|
605
|
-
ActionMailer::Base.deliveries.clear
|
606
|
-
ExceptionHandling.log_error( "Error message is not in list" )
|
607
|
-
assert_emails 1, ActionMailer::Base.deliveries.map { |m| m.body.inspect }
|
608
|
-
end
|
609
|
-
|
610
|
-
context "Exception Handling Mailer" do
|
611
|
-
should "create email" do
|
612
|
-
ExceptionHandling.log_error(exception_1) do |data|
|
613
|
-
data[:request] = { :params => {:id => 10993}, :url => "www.ringrevenue.com" }
|
614
|
-
data[:session] = { :key => "DECAFE" }
|
615
|
-
end
|
616
|
-
assert_emails 1, ActionMailer::Base.deliveries.map { |m| m.body.inspect }
|
617
|
-
assert mail = ActionMailer::Base.deliveries.last
|
618
|
-
assert_equal ['exceptions@example.com'], mail.to
|
619
|
-
assert_equal ['server@example.com'].to_s, mail.from.to_s
|
620
|
-
assert_match /Exception 1/, mail.to_s
|
621
|
-
assert_match /key: DECAFE/, mail.to_s
|
622
|
-
assert_match /id: 10993/, mail.to_s
|
623
|
-
end
|
624
|
-
|
625
|
-
EXPECTED_SMTP_HASH =
|
626
|
-
{
|
627
|
-
:host => 'localhost',
|
628
|
-
:domain => 'localhost.localdomain',
|
629
|
-
:from => 'server@example.com',
|
630
|
-
:to => 'exceptions@example.com'
|
631
|
-
}
|
632
|
-
|
633
|
-
[true, :Synchrony].each do |synchrony_flag|
|
634
|
-
context "EVENTMACHINE_EXCEPTION_HANDLING = #{synchrony_flag}" do
|
635
|
-
setup do
|
636
|
-
set_test_const('EVENTMACHINE_EXCEPTION_HANDLING', synchrony_flag)
|
637
|
-
EventMachineStub.block = nil
|
638
|
-
set_test_const('EventMachine', EventMachineStub)
|
639
|
-
set_test_const('EventMachine::Protocols', Module.new)
|
640
|
-
end
|
641
|
-
|
642
|
-
should "schedule EventMachine STMP when EventMachine defined" do
|
643
|
-
set_test_const('EventMachine::Protocols::SmtpClient', SmtpClientStub)
|
644
|
-
|
645
|
-
ExceptionHandling.log_error(exception_1)
|
646
|
-
assert EventMachineStub.block
|
647
|
-
EventMachineStub.block.call
|
648
|
-
EXPECTED_SMTP_HASH.map { |key, value| assert_equal value, SmtpClientStub.send_hash[key].to_s, SmtpClientStub.send_hash.inspect }
|
649
|
-
assert_equal (synchrony_flag == :Synchrony ? :asend : :send), SmtpClientStub.last_method
|
650
|
-
assert_match /Exception 1/, SmtpClientStub.send_hash[:body]
|
651
|
-
assert_emails 0, ActionMailer::Base.deliveries.map { |m| m.body.inspect }
|
652
|
-
end
|
653
|
-
|
654
|
-
should "log fatal on EventMachine STMP errback" do
|
655
|
-
set_test_const('EventMachine::Protocols::SmtpClient', SmtpClientErrbackStub)
|
656
|
-
ExceptionHandling.logger.expects(:fatal).twice.with do |message|
|
657
|
-
assert message =~ /Failed to email by SMTP: "credential mismatch"/ || message =~ /Exception 1/, message
|
658
|
-
true
|
659
|
-
end
|
660
|
-
ExceptionHandling.log_error(exception_1)
|
661
|
-
assert EventMachineStub.block
|
662
|
-
EventMachineStub.block.call
|
663
|
-
SmtpClientErrbackStub.block.call("credential mismatch")
|
664
|
-
EXPECTED_SMTP_HASH.map { |key, value| assert_equal value, SmtpClientErrbackStub.send_hash[key].to_s, SmtpClientErrbackStub.send_hash.inspect }
|
665
|
-
assert_emails 0, ActionMailer::Base.deliveries.map { |m| m.body.inspect }
|
666
|
-
end
|
667
|
-
end
|
668
|
-
end
|
669
|
-
end
|
670
|
-
|
671
|
-
should "truncate email subject" do
|
672
|
-
text = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM".split('').join("123456789")
|
673
|
-
begin
|
674
|
-
raise text
|
675
|
-
rescue => ex
|
676
|
-
ExceptionHandling.log_error( ex )
|
677
|
-
end
|
678
|
-
assert_emails 1, ActionMailer::Base.deliveries.map { |m| m.inspect }
|
679
|
-
mail = ActionMailer::Base.deliveries.last
|
680
|
-
subject = "test exception: RuntimeError: " + text
|
681
|
-
assert_equal subject[0,300], mail.subject
|
682
|
-
end
|
683
|
-
end
|
684
|
-
|
685
|
-
if defined?(Rails)
|
686
|
-
context "ExceptionHandling.Methods" do
|
687
|
-
setup do
|
688
|
-
@controller = TestController.new
|
689
|
-
end
|
690
|
-
|
691
|
-
teardown do
|
692
|
-
Time.now_override = nil
|
693
|
-
end
|
694
|
-
|
695
|
-
should "set the around filter" do
|
696
|
-
assert_equal :set_current_controller, TestController.around_filter_method
|
697
|
-
assert_nil ExceptionHandling.current_controller
|
698
|
-
@controller.simulate_around_filter( ) do
|
699
|
-
assert_equal @controller, ExceptionHandling.current_controller
|
700
|
-
end
|
701
|
-
assert_nil ExceptionHandling.current_controller
|
702
|
-
end
|
703
|
-
|
704
|
-
should "use the current controller when included in a Model" do
|
705
|
-
ActiveRecord::Base.logger.expects(:fatal).with { |ex| ex =~ /blah/ }
|
706
|
-
@controller.simulate_around_filter( ) do
|
707
|
-
a = TestAdvertiser.new :name => 'Joe Ads'
|
708
|
-
a.test_log_error( ArgumentError.new("blah") )
|
709
|
-
mail = ActionMailer::Base.deliveries.last
|
710
|
-
assert_equal EXCEPTION_HANDLING_MAILER_RECIPIENTS, mail.to
|
711
|
-
assert_match( @controller.request.request_uri, mail.body.to_s )
|
712
|
-
assert_match( Username.first.username.to_s, mail.body.to_s )
|
713
|
-
end
|
714
|
-
end
|
715
|
-
|
716
|
-
should "use the current_controller when available" do
|
717
|
-
ActiveRecord::Base.logger.expects(:fatal).with( ) { |ex| ex =~ /blah/ }
|
718
|
-
@controller.simulate_around_filter do
|
719
|
-
ExceptionHandling.log_error( ArgumentError.new("blah") )
|
720
|
-
mail = ActionMailer::Base.deliveries.last
|
721
|
-
assert_equal EXCEPTION_HANDLING_MAILER_RECIPIENTS, mail.to
|
722
|
-
assert_match( @controller.request.request_uri, mail.body )
|
723
|
-
assert_match( Username.first.username.to_s, mail.body )
|
724
|
-
mail = ActionMailer::Base.deliveries.last
|
725
|
-
assert_equal EXCEPTION_HANDLING_MAILER_RECIPIENTS, mail.to
|
726
|
-
assert_match( @controller.request.request_uri, mail.body.to_s )
|
727
|
-
assert_match( Username.first.username.to_s, mail.body.to_s )
|
728
|
-
assert mail = ActionMailer::Base.deliveries.last
|
729
|
-
assert_equal EXCEPTION_HANDLING_MAILER_RECIPIENTS, mail.to
|
730
|
-
assert_match( @controller.request.request_uri, mail.body.to_s )
|
731
|
-
assert_match( Username.first.username.to_s, mail.body.to_s )
|
732
|
-
end
|
733
|
-
end
|
734
|
-
|
735
|
-
should "report long running controller action" do
|
736
|
-
# If stubbing this causes problems, retreat.
|
737
|
-
Rails.expects(:env).returns('production')
|
738
|
-
ExceptionHandling.logger.expects(:fatal).with { |ex| ex =~ /Long controller action detected in TestController::test_action/ or raise "Unexpected: #{ex.inspect}"}
|
739
|
-
@controller.simulate_around_filter( ) do
|
740
|
-
Time.now_override = 1.hour.from_now
|
741
|
-
end
|
742
|
-
end
|
743
|
-
end
|
744
|
-
|
745
|
-
context "a model object" do
|
746
|
-
setup do
|
747
|
-
@a = TestAdvertiser.new :name => 'Joe Ads'
|
748
|
-
end
|
749
|
-
|
750
|
-
context "with an argument error" do
|
751
|
-
setup do
|
752
|
-
begin
|
753
|
-
raise ArgumentError.new("blah");
|
754
|
-
rescue => ex
|
755
|
-
@argument_error = ex
|
756
|
-
end
|
757
|
-
end
|
758
|
-
|
759
|
-
context "log_error on a model" do
|
760
|
-
should "log errors" do
|
761
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /\(blah\):\n.*exception_handling_test\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
762
|
-
@a.test_log_error( @argument_error )
|
763
|
-
end
|
764
|
-
|
765
|
-
should "log errors from strings" do
|
766
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /\(blah\):\n.*exception_handling\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
767
|
-
@a.test_log_error( "blah" )
|
768
|
-
end
|
769
|
-
|
770
|
-
should "log errors with strings" do
|
771
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /mooo.* \(blah\):\n.*exception_handling_test\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
772
|
-
@a.test_log_error( @argument_error, "mooo" )
|
773
|
-
end
|
774
|
-
end
|
775
|
-
|
776
|
-
context "ensure_escalation on a model" do
|
777
|
-
should "work" do
|
778
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /\(blah\):\n.*exception_handling_test\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
779
|
-
@a.test_ensure_escalation 'Favorite Feature' do
|
780
|
-
raise @argument_error
|
781
|
-
end
|
782
|
-
assert_equal 2, ActionMailer::Base.deliveries.count
|
783
|
-
email = ActionMailer::Base.deliveries.last
|
784
|
-
assert_equal 'development-local Escalation: Favorite Feature', email.subject
|
785
|
-
assert_match 'ArgumentError: blah', email.body.to_s
|
786
|
-
end
|
787
|
-
end
|
788
|
-
|
789
|
-
context "ExceptionHandling.log_error" do
|
790
|
-
should "log errors" do
|
791
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /\(blah\):\n.*exception_handling_test\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
792
|
-
ExceptionHandling.log_error( @argument_error )
|
793
|
-
end
|
794
|
-
|
795
|
-
should "log errors from strings" do
|
796
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /\(blah\):\n.*exception_handling\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
797
|
-
ExceptionHandling.log_error( "blah" )
|
798
|
-
end
|
799
|
-
|
800
|
-
should "log errors with strings" do
|
801
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /mooo.*\(blah\):\n.*exception_handling_test\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
802
|
-
ExceptionHandling.log_error( @argument_error, "mooo" )
|
803
|
-
end
|
804
|
-
end
|
805
|
-
end
|
806
|
-
|
807
|
-
should "log warnings" do
|
808
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /blah/ }
|
809
|
-
@a.test_log_warning("blah")
|
810
|
-
end
|
811
|
-
|
812
|
-
context "ensure_safe on the model" do
|
813
|
-
should "log an exception if an exception is raised." do
|
814
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /\(blah\):\n.*exception_handling_test\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
815
|
-
@a.test_ensure_safe { raise ArgumentError.new("blah") }
|
816
|
-
end
|
817
|
-
|
818
|
-
should "should not log an exception if an exception is not raised." do
|
819
|
-
ExceptionHandling.logger.expects(:fatal).never
|
820
|
-
@a.test_ensure_safe { ; }
|
821
|
-
end
|
822
|
-
|
823
|
-
should "return its value if used during an assignment" do
|
824
|
-
ExceptionHandling.logger.expects(:fatal).never
|
825
|
-
b = @a.test_ensure_safe { 5 }
|
826
|
-
assert_equal 5, b
|
827
|
-
end
|
828
|
-
|
829
|
-
should "return nil if an exception is raised during an assignment" do
|
830
|
-
ExceptionHandling.logger.expects(:fatal).returns(nil)
|
831
|
-
b = @a.test_ensure_safe { raise ArgumentError.new("blah") }
|
832
|
-
assert_nil b
|
833
|
-
end
|
834
|
-
|
835
|
-
should "allow a message to be appended to the error when logged." do
|
836
|
-
ExceptionHandling.logger.expects(:fatal).with( ) { |ex| ex =~ /mooo.*\(blah\):\n.*exception_handling_test\.rb/ or raise "Unexpected: #{ex.inspect}" }
|
837
|
-
b = @a.test_ensure_safe("mooo") { raise ArgumentError.new("blah") }
|
838
|
-
assert_nil b
|
839
|
-
end
|
840
|
-
end
|
841
|
-
end
|
842
|
-
end
|
843
|
-
|
844
|
-
context "Exception mapping" do
|
845
|
-
setup do
|
846
|
-
@data = {
|
847
|
-
:environment=>{
|
848
|
-
'HTTP_HOST' => "localhost",
|
849
|
-
'HTTP_REFERER' => "http://localhost/action/controller/instance",
|
850
|
-
},
|
851
|
-
:session=>{
|
852
|
-
:data=>{
|
853
|
-
:affiliate_id=> defined?(Affiliate) ? Affiliate.first.id : '1',
|
854
|
-
:edit_mode=> true,
|
855
|
-
:advertiser_id=> defined?(Advertiser) ? Advertiser.first.id : '1',
|
856
|
-
:username_id=> defined?(Username) ? Username.first.id : '1',
|
857
|
-
:user_id=> defined?(User) ? User.first.id : '1',
|
858
|
-
:flash=>{},
|
859
|
-
:impersonated_organization_pk=> 'Advertiser_1'
|
860
|
-
}
|
861
|
-
},
|
862
|
-
:request=>{},
|
863
|
-
:backtrace=>["[GEM_ROOT]/gems/actionpack-2.1.0/lib/action_controller/filters.rb:580:in `call_filters'", "[GEM_ROOT]/gems/actionpack-2.1.0/lib/action_controller/filters.rb:601:in `run_before_filters'"],
|
864
|
-
:api_key=>"none",
|
865
|
-
:error_class=>"StandardError",
|
866
|
-
:error=>'Some error message'
|
867
|
-
}
|
868
|
-
end
|
869
|
-
|
870
|
-
should "clean backtraces" do
|
871
|
-
begin
|
872
|
-
raise "test exception"
|
873
|
-
rescue => ex
|
874
|
-
backtrace = ex.backtrace
|
875
|
-
end
|
876
|
-
result = ExceptionHandling.send(:clean_backtrace, ex).to_s
|
877
|
-
assert_not_equal result, backtrace
|
878
|
-
end
|
879
|
-
|
880
|
-
should "clean params" do
|
881
|
-
p = {'password' => 'apple', 'username' => 'sam' }
|
882
|
-
ExceptionHandling.send( :clean_params, p )
|
883
|
-
assert_equal "[FILTERED]", p['password']
|
884
|
-
assert_equal 'sam', p['username']
|
885
|
-
end
|
886
|
-
end
|
887
|
-
|
888
|
-
context "log_perodically" do
|
889
|
-
setup do
|
890
|
-
Time.now_override = Time.now # Freeze time
|
891
|
-
ExceptionHandling.logger.clear
|
892
|
-
end
|
893
|
-
|
894
|
-
teardown do
|
895
|
-
Time.now_override = nil
|
896
|
-
end
|
897
|
-
|
898
|
-
should "log immediately when we are expected to log" do
|
899
|
-
logger_stub = ExceptionHandling.logger
|
900
|
-
|
901
|
-
ExceptionHandling.log_periodically(:test_periodic_exception, 30.minutes, "this will be written")
|
902
|
-
assert_equal 1, logger_stub.logged.size
|
903
|
-
|
904
|
-
Time.now_override = Time.now + 5.minutes
|
905
|
-
ExceptionHandling.log_periodically(:test_periodic_exception, 30.minutes, "this will not be written")
|
906
|
-
assert_equal 1, logger_stub.logged.size
|
907
|
-
|
908
|
-
ExceptionHandling.log_periodically(:test_another_periodic_exception, 30.minutes, "this will be written")
|
909
|
-
assert_equal 2, logger_stub.logged.size
|
910
|
-
|
911
|
-
Time.now_override = Time.now + 26.minutes
|
912
|
-
|
913
|
-
ExceptionHandling.log_periodically(:test_periodic_exception, 30.minutes, "this will be written")
|
914
|
-
assert_equal 3, logger_stub.logged.size
|
915
|
-
end
|
916
|
-
end
|
917
|
-
|
918
|
-
context "Errplane" do
|
919
|
-
module ErrplaneStub
|
920
|
-
end
|
921
|
-
|
922
|
-
setup do
|
923
|
-
set_test_const('Errplane', ErrplaneStub)
|
924
|
-
end
|
925
|
-
|
926
|
-
should "forward exceptions" do
|
927
|
-
ex = data = nil
|
928
|
-
Errplane.expects(:transmit).with do |ex_, data_|
|
929
|
-
ex, data = ex_, data_
|
930
|
-
true
|
931
|
-
end
|
932
|
-
|
933
|
-
ExceptionHandling.log_error(exception_1, "context")
|
934
|
-
|
935
|
-
assert_equal exception_1, ex, ex.inspect
|
936
|
-
custom_data = data[:custom_data]
|
937
|
-
custom_data["error"].include?("context") or raise "Wrong custom_data #{custom_data["error"].inspect}"
|
938
|
-
end
|
939
|
-
|
940
|
-
should "not forward warnings" do
|
941
|
-
never = true
|
942
|
-
Errplane.stubs(:transmit).with do
|
943
|
-
never = false
|
944
|
-
true
|
945
|
-
end
|
946
|
-
|
947
|
-
ExceptionHandling.log_warning("warning message")
|
948
|
-
|
949
|
-
assert never, "transmit should not have been called"
|
950
|
-
end
|
951
|
-
end
|
952
|
-
|
953
|
-
private
|
954
|
-
|
955
|
-
def incrementing_mtime
|
956
|
-
@mtime ||= Time.now
|
957
|
-
@mtime += 1.day
|
958
|
-
end
|
959
|
-
|
960
|
-
def exception_1
|
961
|
-
@ex1 ||=
|
962
|
-
begin
|
963
|
-
raise StandardError, "Exception 1"
|
964
|
-
rescue => ex
|
965
|
-
ex
|
966
|
-
end
|
967
|
-
end
|
968
|
-
|
969
|
-
def exception_2
|
970
|
-
@ex2 ||=
|
971
|
-
begin
|
972
|
-
raise StandardError, "Exception 2"
|
973
|
-
rescue => ex
|
974
|
-
ex
|
975
|
-
end
|
976
|
-
end
|
977
|
-
end
|