activejob-retry 0.0.1 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +22 -0
  3. data/.travis.yml +20 -5
  4. data/CHANGELOG.md +3 -0
  5. data/Gemfile +9 -6
  6. data/Gemfile.lock +63 -51
  7. data/LICENSE +1 -1
  8. data/README.md +57 -25
  9. data/Rakefile +14 -13
  10. data/activejob-retry.gemspec +9 -12
  11. data/lib/active_job/retry.rb +69 -90
  12. data/lib/active_job/retry/constant_backoff_strategy.rb +50 -0
  13. data/lib/active_job/retry/constant_options_validator.rb +76 -0
  14. data/lib/active_job/retry/deserialize_monkey_patch.rb +17 -12
  15. data/lib/active_job/retry/errors.rb +6 -0
  16. data/lib/active_job/retry/variable_backoff_strategy.rb +34 -0
  17. data/lib/active_job/retry/variable_options_validator.rb +56 -0
  18. data/lib/active_job/retry/version.rb +1 -1
  19. data/spec/retry/constant_backoff_strategy_spec.rb +115 -0
  20. data/spec/retry/constant_options_validator_spec.rb +81 -0
  21. data/spec/retry/variable_backoff_strategy_spec.rb +121 -0
  22. data/spec/retry/variable_options_validator_spec.rb +83 -0
  23. data/spec/retry_spec.rb +114 -170
  24. data/spec/spec_helper.rb +3 -2
  25. data/test/adapters/backburner.rb +3 -0
  26. data/test/adapters/delayed_job.rb +7 -0
  27. data/test/adapters/inline.rb +1 -0
  28. data/test/adapters/qu.rb +3 -0
  29. data/test/adapters/que.rb +4 -0
  30. data/test/adapters/queue_classic.rb +2 -0
  31. data/test/adapters/resque.rb +2 -0
  32. data/test/adapters/sidekiq.rb +2 -0
  33. data/test/adapters/sneakers.rb +2 -0
  34. data/test/adapters/sucker_punch.rb +2 -0
  35. data/test/cases/adapter_test.rb +8 -0
  36. data/test/cases/argument_serialization_test.rb +84 -0
  37. data/test/cases/callbacks_test.rb +23 -0
  38. data/test/cases/job_serialization_test.rb +15 -0
  39. data/test/cases/logging_test.rb +114 -0
  40. data/test/cases/queue_naming_test.rb +102 -0
  41. data/test/cases/queuing_test.rb +44 -0
  42. data/test/cases/rescue_test.rb +35 -0
  43. data/test/cases/test_case_test.rb +14 -0
  44. data/test/cases/test_helper_test.rb +226 -0
  45. data/test/helper.rb +21 -0
  46. data/test/integration/queuing_test.rb +46 -0
  47. data/test/jobs/callback_job.rb +31 -0
  48. data/test/jobs/gid_job.rb +10 -0
  49. data/test/jobs/hello_job.rb +9 -0
  50. data/test/jobs/logging_job.rb +12 -0
  51. data/test/jobs/nested_job.rb +12 -0
  52. data/test/jobs/rescue_job.rb +31 -0
  53. data/test/models/person.rb +20 -0
  54. data/test/support/backburner/inline.rb +8 -0
  55. data/test/support/delayed_job/delayed/backend/test.rb +111 -0
  56. data/test/support/delayed_job/delayed/serialization/test.rb +0 -0
  57. data/test/support/integration/adapters/backburner.rb +38 -0
  58. data/test/support/integration/adapters/delayed_job.rb +20 -0
  59. data/test/support/integration/adapters/que.rb +37 -0
  60. data/test/support/integration/adapters/resque.rb +49 -0
  61. data/test/support/integration/adapters/sidekiq.rb +58 -0
  62. data/test/support/integration/dummy_app_template.rb +28 -0
  63. data/test/support/integration/helper.rb +30 -0
  64. data/test/support/integration/jobs_manager.rb +27 -0
  65. data/test/support/integration/test_case_helpers.rb +48 -0
  66. data/test/support/job_buffer.rb +19 -0
  67. data/test/support/que/inline.rb +9 -0
  68. metadata +60 -12
  69. data/lib/active_job-retry.rb +0 -14
  70. data/lib/active_job/retry/exponential_backoff.rb +0 -92
  71. data/lib/active_job/retry/exponential_options_validator.rb +0 -57
  72. data/lib/active_job/retry/invalid_configuration_error.rb +0 -6
  73. data/lib/active_job/retry/options_validator.rb +0 -84
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9dd35a0525fd3f160a488f90b9471f7058a714de
4
- data.tar.gz: 3e423dbca62f4337a765a54f7c212ccd3ef237eb
3
+ metadata.gz: db6f767b064370ffd9a2b32630bcb21c2629ce6a
4
+ data.tar.gz: b8cf9fd6ca868b5acad274131906fa71046e4df6
5
5
  SHA512:
6
- metadata.gz: ac1daad64696deacbfeab3d8e28e1ffff49b7e219580de47f9f02f0867ae5f0977615c019d88f8f9d2afca3561df7b551fcb56a9b3d4ce2ccdea109e117c907a
7
- data.tar.gz: 74b33077ae43b9232eace312851fc9a85165e72c8ae4b1b386f97d109daab75121909fb9a9b7bcec5c7b3e70673ca0d4ab5ed5a16448d7ab7d8769b0b95a7e50
6
+ metadata.gz: b69605d70cced8e95f98147aebcbf132fb3600d44798ef57838febbf74bd7d7587ee9792b0f8cbf5c4682cf4ddd440f6e07dd818cccf4c6de68b0e821e072ecb
7
+ data.tar.gz: 44443de787c728f2e7beeb2fdc4cd62a73bf38a6b61beee1fa3d034d3d822e2b5855372c014f57014ceb288dd3e873d0de38c8c5063e41671c51208435865984
data/.rubocop.yml ADDED
@@ -0,0 +1,22 @@
1
+ AllCops:
2
+ Include:
3
+ - Rakefile
4
+ Exclude:
5
+ - .*/**/*
6
+ - vendor/**
7
+ - test/**/*
8
+
9
+ LineLength:
10
+ Max: 90
11
+
12
+ Style/SignalException:
13
+ EnforcedStyle: 'only_raise'
14
+
15
+ Metrics/MethodLength:
16
+ CountComments: false
17
+
18
+ Style/Documentation:
19
+ Enabled: false
20
+
21
+ Style/DotPosition:
22
+ EnforcedStyle: trailing
data/.travis.yml CHANGED
@@ -1,15 +1,30 @@
1
+ sudo: false
2
+ cache: bundler
3
+
1
4
  language: ruby
2
5
 
3
6
  matrix:
4
7
  allow_failures:
5
- - rvm: jruby-19mode
8
+ - rvm: jruby
6
9
  - rvm: rbx-2
7
10
 
8
11
  rvm:
9
12
  - 1.9.3
10
13
  - 2.0.0
11
- - 2.1.0
12
- - 2.1.1
13
- - 2.1.2
14
- - jruby-19mode
14
+ - 2.1
15
+ - 2.2
16
+ - jruby
15
17
  - rbx-2
18
+
19
+ script:
20
+ - bundle exec rubocop
21
+ - bundle exec rspec spec
22
+ - bundle exec rake test
23
+ - bundle exec rake test:integration
24
+
25
+ services:
26
+ - redis
27
+ - rabbitmq
28
+
29
+ addons:
30
+ postgresql: "9.4"
data/CHANGELOG.md CHANGED
@@ -0,0 +1,3 @@
1
+ ## 0.1.1 - January 1, 2015
2
+
3
+ - Initial release
data/Gemfile CHANGED
@@ -1,17 +1,20 @@
1
1
  source 'https://rubygems.org'
2
+
2
3
  gemspec
3
4
 
4
- group :test do
5
+ group :test, :integration do
6
+ # Queues
5
7
  gem 'resque', require: false
6
8
  gem 'resque-scheduler', require: false
7
9
  gem 'sidekiq', require: false
8
- gem 'sucker_punch', require: false
9
10
  gem 'delayed_job', require: false
10
- gem 'queue_classic', "< 3.0.0", require: false, platforms: :ruby
11
- gem 'sneakers', '0.1.1.pre', require: false
11
+ gem 'delayed_job_active_record', require: false
12
12
  gem 'que', require: false
13
13
  gem 'backburner', require: false
14
- gem 'qu-rails', github: "bkeepers/qu", branch: "master", require: false
15
- gem 'qu-redis', require: false
16
14
  gem 'sequel', require: false
15
+
16
+ # Specs
17
+ gem 'sqlite3'
18
+ gem 'pg'
19
+ gem 'rails'
17
20
  end
data/Gemfile.lock CHANGED
@@ -1,26 +1,19 @@
1
- GIT
2
- remote: git://github.com/bkeepers/qu.git
3
- revision: d098e2657c92e89a6413bebd9c033930759c061f
4
- branch: master
5
- specs:
6
- qu (0.2.0)
7
- qu-rails (0.2.0)
8
- qu (= 0.2.0)
9
- railties (>= 3.2, < 5)
10
- qu-redis (0.2.0)
11
- qu (= 0.2.0)
12
- redis-namespace
13
-
14
1
  PATH
15
2
  remote: .
16
3
  specs:
17
- activejob-retry (0.0.1)
4
+ activejob-retry (0.1.0)
18
5
  activejob (>= 4.2)
19
6
  activesupport (>= 4.2)
20
7
 
21
8
  GEM
22
9
  remote: https://rubygems.org/
23
10
  specs:
11
+ actionmailer (4.2.0)
12
+ actionpack (= 4.2.0)
13
+ actionview (= 4.2.0)
14
+ activejob (= 4.2.0)
15
+ mail (~> 2.5, >= 2.5.4)
16
+ rails-dom-testing (~> 1.0, >= 1.0.5)
24
17
  actionpack (4.2.0)
25
18
  actionview (= 4.2.0)
26
19
  activesupport (= 4.2.0)
@@ -37,65 +30,78 @@ GEM
37
30
  activejob (4.2.0)
38
31
  activesupport (= 4.2.0)
39
32
  globalid (>= 0.3.0)
33
+ activemodel (4.2.0)
34
+ activesupport (= 4.2.0)
35
+ builder (~> 3.1)
36
+ activerecord (4.2.0)
37
+ activemodel (= 4.2.0)
38
+ activesupport (= 4.2.0)
39
+ arel (~> 6.0)
40
40
  activesupport (4.2.0)
41
41
  i18n (~> 0.7)
42
42
  json (~> 1.7, >= 1.7.7)
43
43
  minitest (~> 5.1)
44
44
  thread_safe (~> 0.3, >= 0.3.4)
45
45
  tzinfo (~> 1.1)
46
- amq-protocol (1.9.2)
46
+ arel (6.0.0)
47
+ ast (2.0.0)
48
+ astrolabe (1.3.0)
49
+ parser (>= 2.2.0.pre.3, < 3.0)
47
50
  backburner (0.4.6)
48
51
  beaneater (~> 0.3.1)
49
52
  dante (~> 0.1.5)
50
53
  beaneater (0.3.3)
51
54
  builder (3.2.2)
52
- bunny (1.1.9)
53
- amq-protocol (>= 1.9.2)
54
- byebug (3.5.1)
55
- columnize (~> 0.8)
56
- debugger-linecache (~> 1.2)
57
- slop (~> 3.6)
58
55
  celluloid (0.16.0)
59
56
  timers (~> 4.0.0)
60
- coderay (1.1.0)
61
- columnize (0.9.0)
62
57
  connection_pool (2.1.0)
63
58
  dante (0.1.5)
64
- debugger-linecache (1.2.0)
65
59
  delayed_job (4.0.6)
66
60
  activesupport (>= 3.0, < 5.0)
61
+ delayed_job_active_record (4.0.3)
62
+ activerecord (>= 3.0, < 5.0)
63
+ delayed_job (>= 3.0, < 4.1)
67
64
  diff-lcs (1.2.5)
68
65
  erubis (2.7.0)
69
66
  globalid (0.3.0)
70
67
  activesupport (>= 4.1.0)
68
+ hike (1.2.3)
71
69
  hitimes (1.2.2)
72
70
  i18n (0.7.0)
73
71
  json (1.8.1)
74
72
  loofah (2.0.1)
75
73
  nokogiri (>= 1.5.9)
76
- method_source (0.8.2)
74
+ mail (2.6.3)
75
+ mime-types (>= 1.16, < 3)
76
+ mime-types (2.4.3)
77
77
  mini_portile (0.6.2)
78
78
  minitest (5.5.0)
79
79
  mono_logger (1.1.0)
80
80
  multi_json (1.10.1)
81
81
  nokogiri (1.6.5)
82
82
  mini_portile (~> 0.6.0)
83
+ parser (2.2.0.1)
84
+ ast (>= 1.1, < 3.0)
85
+ slop (~> 3.4, >= 3.4.5)
83
86
  pg (0.17.1)
84
- pry (0.10.1)
85
- coderay (~> 1.1.0)
86
- method_source (~> 0.8.1)
87
- slop (~> 3.4)
88
- pry-byebug (2.0.0)
89
- byebug (~> 3.4)
90
- pry (~> 0.10)
87
+ powerpack (0.0.9)
91
88
  que (0.9.0)
92
- queue_classic (2.2.3)
93
- pg (~> 0.17.0)
94
89
  rack (1.6.0)
95
90
  rack-protection (1.5.3)
96
91
  rack
97
92
  rack-test (0.6.2)
98
93
  rack (>= 1.0)
94
+ rails (4.2.0)
95
+ actionmailer (= 4.2.0)
96
+ actionpack (= 4.2.0)
97
+ actionview (= 4.2.0)
98
+ activejob (= 4.2.0)
99
+ activemodel (= 4.2.0)
100
+ activerecord (= 4.2.0)
101
+ activesupport (= 4.2.0)
102
+ bundler (>= 1.3.0, < 2.0)
103
+ railties (= 4.2.0)
104
+ sprockets-rails
99
105
  rails-deprecated_sanitizer (1.0.3)
100
106
  activesupport (>= 4.2.0.alpha)
101
107
  rails-dom-testing (1.0.5)
@@ -109,6 +115,7 @@ GEM
109
115
  activesupport (= 4.2.0)
110
116
  rake (>= 0.8.7)
111
117
  thor (>= 0.18.1, < 2.0)
118
+ rainbow (2.0.0)
112
119
  rake (10.4.2)
113
120
  redis (3.2.0)
114
121
  redis-namespace (1.5.1)
@@ -139,32 +146,38 @@ GEM
139
146
  rspec-mocks (3.1.3)
140
147
  rspec-support (~> 3.1.0)
141
148
  rspec-support (3.1.2)
149
+ rubocop (0.28.0)
150
+ astrolabe (~> 1.3)
151
+ parser (>= 2.2.0.pre.7, < 3.0)
152
+ powerpack (~> 0.0.6)
153
+ rainbow (>= 1.99.1, < 3.0)
154
+ ruby-progressbar (~> 1.4)
155
+ ruby-progressbar (1.7.1)
142
156
  rufus-scheduler (3.0.9)
143
157
  tzinfo
144
158
  sequel (4.17.0)
145
- serverengine (1.5.10)
146
- sigdump (~> 0.2.2)
147
159
  sidekiq (3.3.0)
148
160
  celluloid (>= 0.16.0)
149
161
  connection_pool (>= 2.0.0)
150
162
  json
151
163
  redis (>= 3.0.6)
152
164
  redis-namespace (>= 1.3.1)
153
- sigdump (0.2.2)
154
165
  sinatra (1.4.5)
155
166
  rack (~> 1.4)
156
167
  rack-protection (~> 1.4)
157
168
  tilt (~> 1.3, >= 1.3.4)
158
169
  slop (3.6.0)
159
- sneakers (0.1.1.pre)
160
- bunny (~> 1.1.3)
161
- serverengine
162
- thor
163
- thread
164
- sucker_punch (1.3.2)
165
- celluloid (~> 0.16.0)
170
+ sprockets (2.12.3)
171
+ hike (~> 1.2)
172
+ multi_json (~> 1.0)
173
+ rack (~> 1.0)
174
+ tilt (~> 1.1, != 1.3.0)
175
+ sprockets-rails (2.2.2)
176
+ actionpack (>= 3.0)
177
+ activesupport (>= 3.0)
178
+ sprockets (>= 2.8, < 4.0)
179
+ sqlite3 (1.3.10)
166
180
  thor (0.19.1)
167
- thread (0.1.4)
168
181
  thread_safe (0.3.4)
169
182
  tilt (1.4.1)
170
183
  timers (4.0.1)
@@ -181,17 +194,16 @@ DEPENDENCIES
181
194
  activejob-retry!
182
195
  backburner
183
196
  delayed_job
184
- pry-byebug
185
- qu-rails!
186
- qu-redis
197
+ delayed_job_active_record
198
+ pg
187
199
  que
188
- queue_classic (< 3.0.0)
200
+ rails
189
201
  rake (>= 10.3)
190
202
  resque
191
203
  resque-scheduler
192
204
  rspec
193
205
  rspec-its
206
+ rubocop
194
207
  sequel
195
208
  sidekiq
196
- sneakers (= 0.1.1.pre)
197
- sucker_punch
209
+ sqlite3
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014 Isaac Seymour
1
+ Copyright (c) 2015 Isaac Seymour
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,35 +1,38 @@
1
- ActiveJob::Retry
1
+ ActiveJob::Retry [![Build Status](https://travis-ci.org/gocardless/activejob-retry.svg?branch=master)](https://travis-ci.org/gocardless/activejob-retry)
2
2
  ================
3
3
 
4
- A DSL for automatically retrying ActiveJobs, with exponential backoff.
4
+ **This is an alpha library** in active development, so the API may change.
5
+
6
+ Automatic retry functionality for ActiveJob. Just `include ActiveJob::Retry` in your job
7
+ class and call one of `constant_retry`, `variable_retry`, or `retry_with` to define your
8
+ retry strategy:
5
9
 
6
10
  ```ruby
7
11
  class ProcessWebhook < ActiveJob::Base
8
12
  include ActiveJob::Retry
9
13
 
10
14
  queue_as :webhooks
11
- retry_with limit: 3, # Attempt three times and then raise (default: 1)
12
- delay: 5, # Wait ~5 seconds between attempts (default: 0)
13
- retry_exceptions: [TimeoutError] # Only retry when these errors are raised (default: all)
14
- # Could alternatively use:
15
- # fatal_exceptions: [StandardError] # Never catch these errors (default: none)
16
15
 
17
- def perform(webhook)
18
- webhook.process!
19
- end
20
- end
21
- ```
16
+ # Constant delay between attempts:
17
+ constant_retry limit: 3, delay: 5, retry_exceptions: [TimeoutError, NetworkError]
22
18
 
23
- With exponential backoff:
19
+ # Or, variable delay between attempts:
20
+ variable_retry delays: [1, 5, 10, 30]
24
21
 
25
- ```ruby
26
- class ProcessWebhook < ActiveJob::Base
27
- include ActiveJob::Retry::ExponentialBackoff
22
+ # You can also use a custom backoff strategy by passing an object which responds to
23
+ # `should_retry?(attempt, exception)`, and `retry_delay(attempt, exception)`
24
+ # to `retry_with`:
25
+ module ChaoticBackoffStrategy
26
+ def self.should_retry?(retry_attempt, exception)
27
+ [true, true, true, true, false].sample
28
+ end
28
29
 
29
- queue_as :webhooks
30
- backoff_with strategy: [1, 5, 10, 30, 60] # Delay for 1, 5, ... seconds between subsequent retries
31
- min_delay_multiplier: 0.8, # Multiply each delay by a random number between
32
- max_delay_multiplier: 1.2 # 0.8 and 1.2 (rounded to nearest second)
30
+ def self.retry_delay(retry_attempt, exception)
31
+ (0..10).to_a.sample
32
+ end
33
+ end
34
+
35
+ retry_with ChaoticBackoffStrategy
33
36
 
34
37
  def perform(webhook)
35
38
  webhook.process!
@@ -37,11 +40,40 @@ class ProcessWebhook < ActiveJob::Base
37
40
  end
38
41
  ```
39
42
 
43
+ #### `constant_retry` options
44
+ `limit`
45
+ : Maximum number of times to attempt the job (default: 1).
46
+
47
+ `unlimited_retries`
48
+ : If set to `true`, this job will be repeated indefinitely until in succeeds. Use with extreme caution.
49
+
50
+ `delay`
51
+ : Time between attempts (default: 0).
52
+
53
+ `retry_exceptions`
54
+ : A whitelist of exceptions to retry (default: nil, i.e. all exceptions will result in a retry).
55
+
56
+ `fatal_exceptions`
57
+ : A blacklist of exceptions to not retry (default: []).
58
+
59
+ #### `variable_retry` options
60
+
61
+ `delays`
62
+ : __required__ An array of delays between attempts. The first attempt will occur whenever you originally enqueued the job to happen.
63
+
64
+ `min_delay_multiplier`
65
+ : If supplied, each delay will be multiplied by a random number between this and `max_delay_multiplier`.
66
+
67
+ `max_delay_multiplier`
68
+ : The other end of the range for `min_delay_multiplier`. If one is supplied, both must be.
69
+
70
+ `retry_exceptions`
71
+ : Same as for `constant_retry`.
72
+
73
+ `fatal_exceptions`
74
+ : Same as for `constant_retry`.
75
+
40
76
  Contributing
41
77
  ------------
42
78
 
43
- * Fork the project.
44
- * Make your feature addition or bug fix.
45
- * Add tests for it.
46
- * Document it in the CHANGELOG.md.
47
- * Open a PR.
79
+ Contributions are very welcome! Please open a PR or issue on this repo.
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'rake/testtask'
2
2
  require 'rubygems/package_task'
3
3
 
4
- ACTIVEJOB_ADAPTERS = %w(backburner delayed_job que resque sidekiq)
4
+ ACTIVEJOB_ADAPTERS = %w(backburner delayed_job que resque)
5
5
 
6
6
  task default: :test
7
7
  task test: 'test:default'
@@ -23,7 +23,7 @@ namespace :test do
23
23
  end
24
24
 
25
25
  task 'env:integration' do
26
- ENV['AJ_INTEGRATION_TESTS'] = "1"
26
+ ENV['AJ_INTEGRATION_TESTS'] = '1'
27
27
  end
28
28
 
29
29
  ACTIVEJOB_ADAPTERS.each do |adapter|
@@ -35,7 +35,7 @@ namespace :test do
35
35
  t.test_files = FileList['test/cases/**/*_test.rb']
36
36
  t.verbose = true
37
37
  t.warning = true
38
- t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
38
+ t.ruby_opts = ['--dev'] if defined?(JRUBY_VERSION)
39
39
  end
40
40
 
41
41
  namespace :isolated do
@@ -43,19 +43,20 @@ namespace :test do
43
43
  dir = File.dirname(__FILE__)
44
44
  Dir.glob("#{dir}/test/cases/**/*_test.rb").all? do |file|
45
45
  sh(Gem.ruby, '-w', "-I#{dir}/lib", "-I#{dir}/test", file)
46
- end or raise 'Failures'
46
+ end || raise('Failures')
47
47
  end
48
48
  end
49
49
 
50
50
  namespace :integration do
51
- Rake::TestTask.new(adapter => ["test:env:#{adapter}", 'test:env:integration']) do |t|
52
- t.description = "Run integration tests for #{adapter}"
53
- t.libs << 'test'
54
- t.test_files = FileList['test/integration/**/*_test.rb']
55
- t.verbose = true
56
- t.warning = true
57
- t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
58
- end
51
+ Rake::TestTask.new(
52
+ adapter => ["test:env:#{adapter}", 'test:env:integration']) do |t|
53
+ t.description = "Run integration tests for #{adapter}"
54
+ t.libs << 'test'
55
+ t.test_files = FileList['test/integration/**/*_test.rb']
56
+ t.verbose = true
57
+ t.warning = true
58
+ t.ruby_opts = ['--dev'] if defined?(JRUBY_VERSION)
59
+ end
59
60
  end
60
61
  end
61
62
  end
@@ -66,7 +67,7 @@ def run_without_aborting(tasks)
66
67
  tasks.each do |task|
67
68
  begin
68
69
  Rake::Task[task].invoke
69
- rescue Exception
70
+ rescue StandardError
70
71
  errors << task
71
72
  end
72
73
  end