pester 0.1.0 → 0.1.1
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/lib/pester/version.rb +1 -1
- data/lib/pester.rb +32 -16
- data/spec/pester_spec.rb +22 -9
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c726cd4ef970107604a3cabf1d26ddf04fffbc45
|
4
|
+
data.tar.gz: 3579a4065f03f7791720e9d98d0c6bdc5a3c57f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e6af9161e42c15a613748d81845adfa8d786b4a5309b41163b87c5d42945968e984e66e84a95f9ba141b2a713c1c30f1a2d5c6b8b8648e516fc1cb0931b84d0
|
7
|
+
data.tar.gz: a5719117192311422b5bce432f1b53cef9d98f12ef3b4e1df6b244d237709353ce64af6152c015b75910226b010119abadd890cc23a5f15eeebf34c441b0f450
|
data/lib/pester/version.rb
CHANGED
data/lib/pester.rb
CHANGED
@@ -26,6 +26,10 @@ module Pester
|
|
26
26
|
# Options:
|
27
27
|
# retry_error_classes - A single or array of exceptions to retry on. Thrown exceptions not in this list
|
28
28
|
# (including parent/sub-classes) will be reraised
|
29
|
+
# retry_error_messages - A single or array of exception messages to retry on. If only this options is passed,
|
30
|
+
# any exception with a message containing one of these strings will be retried. If this
|
31
|
+
# option is passed along with retry_error_classes, retry will only happen when both the
|
32
|
+
# class and the message match the exception. Strings and regexes are both permitted.
|
29
33
|
# reraise_error_classes - A single or array of exceptions to always re-raiseon. Thrown exceptions not in
|
30
34
|
# this list (including parent/sub-classes) will be retried
|
31
35
|
# max_attempts - Max number of attempts to retry
|
@@ -33,18 +37,14 @@ module Pester
|
|
33
37
|
# passed to retry_with_backoff will retry first after 2 seconds, then 4, then 6, et al.
|
34
38
|
# on_retry - A Proc to be called on each successive failure, before the next retry
|
35
39
|
# on_max_attempts_exceeded - A Proc to be called when attempt_num >= max_attempts - 1
|
36
|
-
#
|
37
|
-
# logic, non-matches will cause the exception to be reraised
|
40
|
+
# logger - Where to log the output
|
38
41
|
#
|
39
42
|
# Usage:
|
40
|
-
# retry_action do
|
43
|
+
# retry_action(retry_error_classes: [Mysql2::Error]) do
|
41
44
|
# puts 'trying to remove a directory'
|
42
45
|
# FileUtils.rm_r(directory)
|
43
46
|
# end
|
44
|
-
|
45
|
-
# retryable(error_classes: Mysql2::Error, message: /^Lost connection to MySQL server/, max_attempts: 2) do
|
46
|
-
# ActiveRecord::Base.connection.execute("LONG MYSQL STATEMENT")
|
47
|
-
# end
|
47
|
+
|
48
48
|
def self.retry_action(opts = {}, &block)
|
49
49
|
merge_defaults(opts)
|
50
50
|
if opts[:retry_error_classes] && opts[:reraise_error_classes]
|
@@ -53,16 +53,10 @@ module Pester
|
|
53
53
|
|
54
54
|
opts[:max_attempts].times do |attempt_num|
|
55
55
|
begin
|
56
|
-
|
57
|
-
return result
|
56
|
+
return yield(block)
|
58
57
|
rescue => e
|
59
|
-
|
60
|
-
|
61
|
-
message_reraise = opts[:message] && !e.message[opts[:message]]
|
62
|
-
|
63
|
-
if class_reraise || message_reraise || reraise_error
|
64
|
-
match_type = class_reraise ? 'class' : 'message'
|
65
|
-
opts[:logger].warn("Reraising exception from inside retry_action because provided #{match_type} was not matched.")
|
58
|
+
unless should_retry?(e, opts)
|
59
|
+
opts[:logger].warn('Reraising exception from inside retry_action.')
|
66
60
|
raise
|
67
61
|
end
|
68
62
|
|
@@ -72,6 +66,7 @@ module Pester
|
|
72
66
|
opts[:logger].warn("Failure encountered: #{e}, backing off and trying again #{attempts_left} more times. Trace: #{trace}")
|
73
67
|
opts[:on_retry].call(attempt_num, opts[:delay_interval])
|
74
68
|
else
|
69
|
+
# Careful here because you will get back the return value of the on_max_attempts_exceeded proc!
|
75
70
|
return opts[:on_max_attempts_exceeded].call(opts[:logger], opts[:max_attempts], e)
|
76
71
|
end
|
77
72
|
end
|
@@ -80,8 +75,29 @@ module Pester
|
|
80
75
|
|
81
76
|
private
|
82
77
|
|
78
|
+
def self.should_retry?(e, opts = {})
|
79
|
+
retry_error_classes = opts[:retry_error_classes]
|
80
|
+
retry_error_messages = opts[:retry_error_messages]
|
81
|
+
reraise_error_classes = opts[:reraise_error_classes]
|
82
|
+
|
83
|
+
if retry_error_classes
|
84
|
+
if retry_error_messages
|
85
|
+
retry_error_classes.include?(e.class) && retry_error_messages.any? { |m| e.message[m] }
|
86
|
+
else
|
87
|
+
retry_error_classes.include?(e.class)
|
88
|
+
end
|
89
|
+
elsif retry_error_messages
|
90
|
+
retry_error_messages.any? { |m| e.message[m] }
|
91
|
+
elsif reraise_error_classes && reraise_error_classes.include?(e.class)
|
92
|
+
false
|
93
|
+
else
|
94
|
+
true
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
83
98
|
def self.merge_defaults(opts)
|
84
99
|
opts[:retry_error_classes] = opts[:retry_error_classes] ? Array(opts[:retry_error_classes]) : nil
|
100
|
+
opts[:retry_error_messages] = opts[:retry_error_messages] ? Array(opts[:retry_error_messages]) : nil
|
85
101
|
opts[:reraise_error_classes] = opts[:reraise_error_classes] ? Array(opts[:reraise_error_classes]) : nil
|
86
102
|
opts[:max_attempts] ||= 4
|
87
103
|
opts[:delay_interval] ||= 30
|
data/spec/pester_spec.rb
CHANGED
@@ -55,7 +55,6 @@ shared_examples 'raises an error only in the correct cases with a retry class' d
|
|
55
55
|
let(:actual_error_message) { matching_error_message }
|
56
56
|
|
57
57
|
it_has_behavior "doesn't raise an error"
|
58
|
-
|
59
58
|
it_has_behavior 'returns and succeeds'
|
60
59
|
end
|
61
60
|
end
|
@@ -66,7 +65,6 @@ shared_examples 'raises an error only in the correct cases with a reraise class'
|
|
66
65
|
let(:actual_error_message) { non_matching_error_message }
|
67
66
|
|
68
67
|
it_has_behavior "doesn't raise an error"
|
69
|
-
|
70
68
|
it_has_behavior 'returns and succeeds'
|
71
69
|
end
|
72
70
|
|
@@ -88,7 +86,6 @@ describe 'retry_action' do
|
|
88
86
|
let(:options) { { delay_interval: 0, logger: null_logger } }
|
89
87
|
|
90
88
|
it_has_behavior "doesn't raise an error"
|
91
|
-
|
92
89
|
it_has_behavior 'returns and succeeds'
|
93
90
|
end
|
94
91
|
|
@@ -97,7 +94,6 @@ describe 'retry_action' do
|
|
97
94
|
let(:options) { { max_attempts: 3, logger: null_logger } }
|
98
95
|
|
99
96
|
it_has_behavior "doesn't raise an error"
|
100
|
-
|
101
97
|
it_has_behavior 'returns and succeeds'
|
102
98
|
end
|
103
99
|
|
@@ -111,17 +107,34 @@ describe 'retry_action' do
|
|
111
107
|
it_has_behavior 'raises an error'
|
112
108
|
end
|
113
109
|
|
114
|
-
context 'with on_max_attempts_exceeded specified
|
115
|
-
let(:do_nothing_proc) { proc {} }
|
110
|
+
context 'with on_max_attempts_exceeded proc specified' do
|
116
111
|
let(:options) do
|
117
112
|
{
|
118
113
|
max_attempts: max_attempts,
|
119
|
-
on_max_attempts_exceeded:
|
114
|
+
on_max_attempts_exceeded: proc_to_call,
|
120
115
|
logger: null_logger
|
121
116
|
}
|
122
117
|
end
|
123
118
|
|
124
|
-
|
119
|
+
context 'which does not do anything' do
|
120
|
+
let(:proc_to_call) { proc {} }
|
121
|
+
it_has_behavior "doesn't raise an error"
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'which reraises' do
|
125
|
+
let(:proc_to_call) { Behaviors::WarnAndReraise }
|
126
|
+
it_has_behavior 'raises an error'
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'which returns a value' do
|
130
|
+
let(:return_value) { 'return_value' }
|
131
|
+
let(:proc_to_call) { proc { return_value } }
|
132
|
+
it_has_behavior "doesn't raise an error"
|
133
|
+
|
134
|
+
it 'should return the result of the proc' do
|
135
|
+
expect(Pester.retry_action(options) { action }).to eq(return_value)
|
136
|
+
end
|
137
|
+
end
|
125
138
|
end
|
126
139
|
end
|
127
140
|
|
@@ -138,7 +151,7 @@ describe 'retry_action' do
|
|
138
151
|
let(:options) do
|
139
152
|
{
|
140
153
|
retry_error_classes: expected_error_classes,
|
141
|
-
|
154
|
+
retry_error_messages: /^Lost connection to MySQL server/,
|
142
155
|
max_attempts: 10,
|
143
156
|
logger: null_logger
|
144
157
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pester
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc Bollinger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|