forklift_etl 1.0.19 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OTg3Mzg3YTI0MDg0YTMyMDZiNWZjYWNiNTllNmYwZWZjMGYzZTQxOA==
4
+ YjE2NGE4ZGQ0N2M3YWI2OTE4MDdkMGIzYTdhZTUzOWRmNzM0YzU3MQ==
5
5
  data.tar.gz: !binary |-
6
- YzI1NWNkZWE0MzRlMTQ2NDQ5ZDc0MGYxMTUyYWQ1ZWRmMGRkYmEzYQ==
6
+ N2EzZTBmNDFhZjEyMTQ3MzZkNmZkMDU3NmU3NGY1MzUyYmY2YmU1MQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MzI0NWNhOWFiNjViODEzNDQzOWRjNTFhZmUwMDdhYWIyMzIxNzE2MWM5ZDdm
10
- ZTJlMTBjMjY1MjY4NDUzNjg5YjAxNGI4ODQ3MDYzMjNjOWU2NjFjN2Y1NzFi
11
- NDBjYmUzODA0YmNlNmY4OTk3YWIzMmNhNzcwYmM3ZjUwYzFkM2Q=
9
+ NTQyNzc0OGI0YzMyOGQyNzE4YmQ3MDBlMDEwMDk2ZjQ4ODFlMTI1MmU2M2Mx
10
+ MzJjZDg2NzA1Y2Y1NDVmOWU0NTAzNDhkNmRhMGFjNGY2ZmE0MGYyYzJmNzBh
11
+ MGU5NmE3NmYyMTE2MzRjMTc2MzIwZjYwZTE3MWViOTE5ZmRlMDc=
12
12
  data.tar.gz: !binary |-
13
- MjM1NWZkZWI2MDJhYmNmZmQ2ZGJhZDk3Y2M3YzNmODBhYjhjY2JiNzU3MTgy
14
- ZThmM2Y5OWExNjZjYjU0YWNiYWZhZDdhYWE3YjE1MDgzODhkM2MxODk4ZWI0
15
- OTA4ZGEzOWI4ZDdmMTdlNjA4OGIzZDQ2YmVkYzY1NzFjOWM5ZjY=
13
+ N2EwNjZiM2JlNzQzOTFlNGUzM2I5YWEwM2Y0ZGRlMjUyZTZhZTlkZWQ3MTJh
14
+ NzA3YTE5ZDgzMTkxMzFjZjZiMWYyYzMzZTEzZjVlMDg0NTlhYWUyNDBlODJm
15
+ Njk2ZGJmOTIwOTgyOWFkNTRkMTFkYjZhMjFkZDMzODZhOGJhOWQ=
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- forklift_etl (1.0.19)
4
+ forklift_etl (1.1.0)
5
5
  activesupport (~> 4.0, >= 4.0.0)
6
6
  elasticsearch (~> 1.0, >= 1.0.0)
7
7
  lumberjack (~> 1.0, >= 1.0.0)
data/lib/forklift/plan.rb CHANGED
@@ -37,17 +37,25 @@ module Forklift
37
37
  logger.debug "loaded a #{type.camelcase} connection from #{f}"
38
38
  rescue Exception => e
39
39
  logger.fatal "cannot create a class type of #{loader} from #{f} | #{e}"
40
- raise e
40
+ # raise e ## Don't raise here, but let a step fail so the error_handler can report
41
41
  end
42
42
  end
43
43
  end
44
44
 
45
+
46
+ def default_error_handler
47
+ return lambda {|name, e| raise e }
48
+ end
49
+
45
50
  def step(*args, &block)
46
- name = args[0].to_sym
51
+ name = args[0].to_sym
52
+ error_handler = default_error_handler
53
+ error_handler = args[1] unless args[1].nil?
47
54
  self.steps[name] = {
48
- :ran => false,
49
- :to_run => false,
50
- :block => block
55
+ :ran => false,
56
+ :to_run => false,
57
+ :block => block,
58
+ :error_handler => error_handler,
51
59
  }
52
60
  end
53
61
 
@@ -63,8 +71,12 @@ module Forklift
63
71
  self.logger.log "skipping step `#{name}`"
64
72
  else
65
73
  self.logger.log "*** step: #{name} ***"
66
- step[:block].call
67
- step[:ran] = true
74
+ begin
75
+ step[:block].call
76
+ step[:ran] = true
77
+ rescue Exception => e
78
+ step[:error_handler].call(name, e)
79
+ end
68
80
  end
69
81
  end
70
82
  end
@@ -1,3 +1,3 @@
1
1
  module Forklift
2
- VERSION = "1.0.19"
2
+ VERSION = "1.1.0"
3
3
  end
data/readme.md CHANGED
@@ -265,6 +265,29 @@ end
265
265
 
266
266
  When you use steps, you can run your whole plan, or just part if it with command line arguments. For example, `forklift plan.rb "Elasticsearch Import"` would just run that single portion of the plan. Note that any parts of your plan not within a step will be run each time.
267
267
 
268
+ ### Error Handling
269
+
270
+ By default, exceptions within your plan will raise and crash your application. However, you can pass an optional `error_handler` lambda to your step about how to handle the error. the `error_handler` will be passed (`step_name`,`exception`). If you don't re-raise within your error handler, your plan will continue to excecute. For example:
271
+
272
+ ```ruby
273
+
274
+ error_handler = lambda { |name, exception|
275
+ if exception.class =~ /connection/
276
+ # I can't connect, I should halt
277
+ raise e
278
+ elsif exception.class =~ /SoftError/
279
+ # this type of error is OK
280
+ else
281
+ raise e
282
+ end
283
+ }
284
+
285
+ plan.step('a_complex_step', error_handler){
286
+ # ...
287
+ }
288
+
289
+ ```
290
+
268
291
  ## Transports
269
292
 
270
293
  Transports are how you interact with your data. Every transport defines `read` and `write` methods which handle arrays of data objects (and the helper methods required).
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'misc forklift core' do
4
+ describe 'error handling' do
5
+
6
+ it "un-caught errors will raise" do
7
+ plan = SpecPlan.new
8
+ expect{
9
+ plan.do! {
10
+ plan.step("step_a"){ raise 'BREAK' }
11
+ }
12
+ }.to raise_error 'BREAK'
13
+ plan.pid.delete!
14
+ end
15
+
16
+ it 'can make error handlers' do
17
+ plan = SpecPlan.new
18
+ name = ''
19
+ ex = ''
20
+ error_handler = lambda{ |n, e|
21
+ ex = e
22
+ name = n
23
+ }
24
+ plan.do! {
25
+ plan.step("step_a", error_handler){ raise 'BREAK' }
26
+ }
27
+
28
+ expect(name).to eql :step_a
29
+ expect(ex.to_s).to eql 'BREAK'
30
+ end
31
+
32
+ end
33
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forklift_etl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.19
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Tahler
@@ -179,6 +179,7 @@ files:
179
179
  - spec/template/spec_email_template.erb
180
180
  - spec/unit/connection/mysql_spec.rb
181
181
  - spec/unit/misc/email_spec.rb
182
+ - spec/unit/misc/error_spec.rb
182
183
  - spec/unit/misc/pid_spec.rb
183
184
  - spec/unit/misc/step_spec.rb
184
185
  - template/destination.yml
@@ -237,6 +238,7 @@ test_files:
237
238
  - spec/template/spec_email_template.erb
238
239
  - spec/unit/connection/mysql_spec.rb
239
240
  - spec/unit/misc/email_spec.rb
241
+ - spec/unit/misc/error_spec.rb
240
242
  - spec/unit/misc/pid_spec.rb
241
243
  - spec/unit/misc/step_spec.rb
242
244
  has_rdoc: