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