decouplio 1.0.0alpha3 → 1.0.0alpha7

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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +11 -1
  3. data/.rubocop.yml +6 -0
  4. data/.ruby-version +1 -1
  5. data/README.md +2 -17
  6. data/decouplio.gemspec +4 -4
  7. data/lib/decouplio/action.rb +13 -3
  8. data/lib/decouplio/composer.rb +24 -3
  9. data/lib/decouplio/const/doby_aide_options.rb +1 -0
  10. data/lib/decouplio/const/error_messages.rb +9 -0
  11. data/lib/decouplio/const/step_options.rb +16 -0
  12. data/lib/decouplio/default_error_handler.rb +21 -6
  13. data/lib/decouplio/errors/execution_error.rb +20 -0
  14. data/lib/decouplio/errors/step_is_not_defined_for_pass_error.rb +27 -0
  15. data/lib/decouplio/logic_dsl.rb +52 -3
  16. data/lib/decouplio/options_validator.rb +46 -10
  17. data/lib/decouplio/steps/base_resq.rb +13 -3
  18. data/lib/decouplio/steps/service_fail.rb +4 -2
  19. data/lib/decouplio/steps/service_pass.rb +4 -2
  20. data/lib/decouplio/steps/service_step.rb +4 -2
  21. data/lib/decouplio/version.rb +1 -1
  22. metadata +14 -39
  23. data/docs/_config.yml +0 -1
  24. data/docs/aide.rb +0 -59
  25. data/docs/benchmarks.md +0 -1
  26. data/docs/context.md +0 -74
  27. data/docs/context.rb +0 -62
  28. data/docs/doby.rb +0 -38
  29. data/docs/doby_aide.md +0 -208
  30. data/docs/error_store.md +0 -347
  31. data/docs/error_store.rb +0 -202
  32. data/docs/fail.md +0 -1159
  33. data/docs/fail.rb +0 -859
  34. data/docs/index.md +0 -25
  35. data/docs/inner_action.md +0 -63
  36. data/docs/inner_action.rb +0 -43
  37. data/docs/logic_block.md +0 -29
  38. data/docs/octo.md +0 -326
  39. data/docs/octo.rb +0 -164
  40. data/docs/pass.md +0 -309
  41. data/docs/pass.rb +0 -213
  42. data/docs/quick_start.md +0 -71
  43. data/docs/quick_start.rb +0 -38
  44. data/docs/resq.md +0 -263
  45. data/docs/resq.rb +0 -176
  46. data/docs/step.md +0 -885
  47. data/docs/step.rb +0 -627
  48. data/docs/step_as_a_service.md +0 -123
  49. data/docs/step_as_a_service.rb +0 -77
  50. data/docs/wrap.md +0 -240
  51. data/docs/wrap.rb +0 -137
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b52142f648d5043e84d6daa6b36026f33d01a6bd9197d5e6f65ac0fb51abac81
4
- data.tar.gz: 7825cc21ae535df0c950c7b5eaf34264d37f6fe13f346282bc3a15e88e4e8b8e
3
+ metadata.gz: b142d4fd94ec689714987c59946aab6c14d7d857a4aa11e55c624c5f7975e622
4
+ data.tar.gz: fc96e94c4d3358fda4eca1e80bfaeb7021a444bc5d9d1ff41b2b1b5f2283dbda
5
5
  SHA512:
6
- metadata.gz: 395c7ca0d0618abd369307426edba5ada1d4dc002f55ff8c0906205e08924a07ec60b0905fd2031860a7b32effbe88265139faf397972ea1359448b5c1572ebb
7
- data.tar.gz: 0fa93d697696700e24758eb3b774d183b1e24486a5846273c24d6ff7dc3684876b587e0afb90165bdb3f8bde8deeee938fc78d90361b4d0d2c193eeec7870ac0
6
+ metadata.gz: 1fc456438780d78c73280883a8b780148568e0a3ac5a2d21162575c73be6a7401378d6a37367aa31f28878226a274a27803da6ecf2b8b2e976b04b536829f3c1
7
+ data.tar.gz: 760d3c4a61d0985b4b49633f3c010107a5833e241ac133613439f9f9f031417e022af02ccef23e77681db22d6fdaeb3d186a18d46237bcd216a22dc0388f77eb
data/.circleci/config.yml CHANGED
@@ -3,7 +3,7 @@ version: 2.1
3
3
  executors:
4
4
  test_executor:
5
5
  docker:
6
- - image: circleci/ruby:${RUBY_VERSION}
6
+ - image: cimg/ruby:${RUBY_VERSION}
7
7
  working_directory: ~/decouplio
8
8
 
9
9
  jobs:
@@ -51,3 +51,13 @@ workflows:
51
51
  name: 'ruby 3.0.3'
52
52
  ruby_version: 3.0.3
53
53
  bundler_version: 2.2.32
54
+ # TODO: Currently rspec-mocks has some issue, or maybe decouplio has an issue
55
+ # needs to be investigated
56
+ # 3 specs are failing
57
+ # rspec ./spec/resq_spec.rb:174
58
+ # rspec ./spec/resq_spec.rb:286
59
+ # rspec ./spec/resq_spec.rb:398
60
+ # - build:
61
+ # name: 'ruby 3.1.2'
62
+ # ruby_version: 3.1.2
63
+ # bundler_version: 2.2.32
data/.rubocop.yml CHANGED
@@ -108,3 +108,9 @@ Naming/PredicateName:
108
108
  Naming/MethodParameterName:
109
109
  Exclude:
110
110
  - spec/support/cases/**/*
111
+
112
+ Naming/RescuedExceptionsVariableName:
113
+ Enabled: false
114
+
115
+ Layout/LineContinuationSpacing:
116
+ Enabled: false
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.7.0
1
+ 2.7.6
data/README.md CHANGED
@@ -25,26 +25,11 @@ Or install it by yourself:
25
25
  - 2.7
26
26
  - 3.0
27
27
 
28
- ### Docs
29
-
30
- - [Quick start](https://github.com/differencialx/decouplio/blob/master/docs/quick_start.md)
31
- - [Logic block](https://github.com/differencialx/decouplio/blob/master/docs/logic_block.md)
32
- - [Context](https://github.com/differencialx/decouplio/blob/master/docs/context.md)
33
- - [Step](https://github.com/differencialx/decouplio/blob/master/docs/step.md)
34
- - [Fail](https://github.com/differencialx/decouplio/blob/master/docs/fail.md)
35
- - [Pass](https://github.com/differencialx/decouplio/blob/master/docs/pass.md)
36
- - [Octo](https://github.com/differencialx/decouplio/blob/master/docs/octo.md)
37
- - [Wrap](https://github.com/differencialx/decouplio/blob/master/docs/wrap.md)
38
- - [Resq](https://github.com/differencialx/decouplio/blob/master/docs/resq.md)
39
- - [Inner action](https://github.com/differencialx/decouplio/blob/master/docs/inner_action.md)
40
- - [Doby/Aide](https://github.com/differencialx/decouplio/blob/master/docs/doby_aide.md)
41
- - [Step as a service](https://github.com/differencialx/decouplio/blob/master/docs/step_as_a_service.md)
42
- - [Error store](https://github.com/differencialx/decouplio/blob/master/docs/error_store.md)
43
- - [Benchmarks](https://github.com/differencialx/decouplio/blob/master/docs/benchmarks.md)
28
+ ### [Documentation is HERE](https://differencialx.github.io/decouplio.github.io/)
44
29
 
45
30
  ## Contributing
46
31
 
47
- Bug reports and pull requests are welcome on GitHub at https://github.com/differencialx/decouplio.
32
+ Bug reports and pull requests are welcome on GitHub at https://github.com/differencialx/decouplio/issues.
48
33
 
49
34
  More detailed description for contribution process will be added later.
50
35
 
data/decouplio.gemspec CHANGED
@@ -12,13 +12,13 @@ Gem::Specification.new do |spec|
12
12
 
13
13
  spec.summary = 'Gem for business logic encapsulation'
14
14
  spec.description = "Decouplio is a zero dependency, thread safe and framework agnostic gem designed to encapsulate application business logic. It's reverse engineered through TDD and inspired by such frameworks and gems like Trailblazer, Interactor."
15
- spec.homepage = 'https://github.com/differencialx/decouplio'
15
+ spec.homepage = 'https://differencialx.github.io/decouplio.github.io/'
16
16
  spec.license = 'MIT'
17
17
 
18
18
  if spec.respond_to?(:metadata)
19
19
  spec.metadata['homepage_uri'] = spec.homepage
20
- spec.metadata['source_code_uri'] = 'https://github.com/differencialx/decouplio'
21
- spec.metadata['changelog_uri'] = 'https://github.com/differencialx/decouplio/CHANGELOG.md'
20
+ spec.metadata['source_code_uri'] = 'https://github.com/differencialx/decouplio/blob/master/docs'
21
+ spec.metadata['changelog_uri'] = 'https://github.com/differencialx/decouplio/blob/master/docs/CHANGELOG.md'
22
22
  else
23
23
  raise 'RubyGems 2.0 or newer is required to protect against ' \
24
24
  'public gem pushes.'
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.add_development_dependency 'bundler', '~> 2'
35
35
  spec.add_development_dependency 'pry-byebug'
36
36
  spec.add_development_dependency 'rake', '>= 12.3.2'
37
- spec.add_development_dependency 'rspec', '~> 3.0'
37
+ spec.add_development_dependency 'rspec', '3.10'
38
38
  spec.add_development_dependency 'rubocop'
39
39
  spec.add_development_dependency 'rubocop-rspec'
40
40
  end
@@ -7,14 +7,13 @@ require_relative 'default_error_handler'
7
7
  require_relative 'errors/logic_redefinition_error'
8
8
  require_relative 'errors/logic_is_not_defined_error'
9
9
  require_relative 'errors/error_store_error'
10
+ require_relative 'errors/execution_error'
10
11
  require_relative 'const/results'
11
12
 
12
13
  module Decouplio
13
14
  class Action
14
- PREVIOUS_STEP_INDEX = -2
15
-
16
15
  extend Forwardable
17
- def_delegators :@error_store, :errors, :add_error
16
+ def_delegators :@error_store, :errors, :add_error, :error_status
18
17
  attr_reader :railway_flow, :ctx, :error_store
19
18
 
20
19
  def initialize(
@@ -99,6 +98,17 @@ module Decouplio
99
98
  instance
100
99
  end
101
100
 
101
+ def call!(**params)
102
+ instance = call(**params)
103
+ if instance.failure?
104
+ raise Decouplio::Errors::ExecutionError.new(
105
+ action: instance
106
+ )
107
+ else
108
+ instance
109
+ end
110
+ end
111
+
102
112
  private
103
113
 
104
114
  def inherited(child_class)
@@ -205,14 +205,16 @@ module Decouplio
205
205
  def create_resq_pass(stp, flow)
206
206
  Decouplio::Steps::ResqPass.new(
207
207
  handler_hash: stp[:handler_hash],
208
- step_to_resq: create_step_instance(stp[:step_to_resq], flow)
208
+ step_to_resq: create_step_instance(stp[:step_to_resq], flow),
209
+ on_error_type: error_type(flow, stp)
209
210
  )
210
211
  end
211
212
 
212
213
  def create_resq_fail(stp, flow)
213
214
  Decouplio::Steps::ResqFail.new(
214
215
  handler_hash: stp[:handler_hash],
215
- step_to_resq: create_step_instance(stp[:step_to_resq], flow)
216
+ step_to_resq: create_step_instance(stp[:step_to_resq], flow),
217
+ on_error_type: error_type(flow, stp)
216
218
  )
217
219
  end
218
220
 
@@ -247,6 +249,7 @@ module Decouplio
247
249
  Decouplio::Steps::ServiceStep.new(
248
250
  name: stp[:name],
249
251
  service: stp[:service],
252
+ args: stp[:_args],
250
253
  on_success_type: success_type(flow, stp),
251
254
  on_failure_type: failure_type(flow, stp)
252
255
  )
@@ -256,6 +259,7 @@ module Decouplio
256
259
  Decouplio::Steps::ServiceFail.new(
257
260
  name: stp[:name],
258
261
  service: stp[:service],
262
+ args: stp[:_args],
259
263
  on_success_type: success_type(flow, stp),
260
264
  on_failure_type: failure_type(flow, stp)
261
265
  )
@@ -265,6 +269,7 @@ module Decouplio
265
269
  Decouplio::Steps::ServicePass.new(
266
270
  name: stp[:name],
267
271
  service: stp[:service],
272
+ args: stp[:_args],
268
273
  on_success_type: success_type(flow, stp),
269
274
  on_failure_type: failure_type(flow, stp)
270
275
  )
@@ -467,7 +472,22 @@ module Decouplio
467
472
  step_id = stp.dig(:flow, Decouplio::Const::Results::FAIL)
468
473
  if step_id.nil? && Decouplio::Const::Results::STEP_PASS == stp[:on_failure]
469
474
  Decouplio::Const::Results::STEP_PASS
470
- elsif step_id.nil? && Decouplio::Const::Results::STEP_FAIL == stp[:on_on_failure]
475
+ elsif step_id.nil? && Decouplio::Const::Results::STEP_FAIL == stp[:on_failure]
476
+ Decouplio::Const::Results::STEP_FAIL
477
+ else
478
+ Decouplio::Const::Types::FAIL_FLOW.include?(
479
+ flow[step_id]&.[](:type)
480
+ )
481
+ end
482
+ end
483
+
484
+ def error_type(flow, stp)
485
+ return :finish_him if [:on_error].include?(finish_him(stp))
486
+
487
+ step_id = stp.dig(:flow, Decouplio::Const::Results::ERROR)
488
+ if step_id.nil? && Decouplio::Const::Results::STEP_PASS == stp[:on_error]
489
+ Decouplio::Const::Results::STEP_PASS
490
+ elsif step_id.nil? && Decouplio::Const::Results::STEP_FAIL == stp[:on_error]
471
491
  Decouplio::Const::Results::STEP_FAIL
472
492
  else
473
493
  Decouplio::Const::Types::FAIL_FLOW.include?(
@@ -576,6 +596,7 @@ module Decouplio
576
596
  options_for_resq = stp[:step_to_resq].slice(
577
597
  :on_success,
578
598
  :on_failure,
599
+ :on_error,
579
600
  :finish_him,
580
601
  :if,
581
602
  :unless
@@ -6,6 +6,7 @@ module Decouplio
6
6
  ALLOWED = %i[
7
7
  on_success
8
8
  on_failure
9
+ on_error
9
10
  finish_him
10
11
  if
11
12
  unless
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decouplio
4
+ module Const
5
+ module ErrorMessages
6
+ EXECUTION_ERROR = 'Action failed.'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decouplio
4
+ module Const
5
+ module StepOptions
6
+ ALLOWED = %i[
7
+ on_success
8
+ on_failure
9
+ on_error
10
+ finish_him
11
+ if
12
+ unless
13
+ ].freeze
14
+ end
15
+ end
16
+ end
@@ -2,17 +2,32 @@
2
2
 
3
3
  module Decouplio
4
4
  class DefaultErrorHandler
5
- attr_reader :errors
5
+ attr_reader :errors, :status
6
6
 
7
7
  def initialize
8
8
  @errors = {}
9
+ @status = nil
9
10
  end
10
11
 
11
- def add_error(key, message)
12
- @errors.store(
13
- key,
14
- (@errors[key] || []) + [message].flatten
15
- )
12
+ def add_error(*args)
13
+ case args.size
14
+ when 1
15
+ args[0].each do |key, message|
16
+ @errors.store(
17
+ key,
18
+ (@errors[key] || []) + [message].flatten
19
+ )
20
+ end
21
+ when 2
22
+ @errors.store(
23
+ args[0],
24
+ (@errors[args[0]] || []) + [args[1]].flatten
25
+ )
26
+ end
27
+ end
28
+
29
+ def error_status(err_st)
30
+ @status = err_st
16
31
  end
17
32
 
18
33
  def merge(error_store)
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../const/error_messages'
4
+
5
+ module Decouplio
6
+ module Errors
7
+ class ExecutionError < StandardError
8
+ attr_reader :action
9
+
10
+ def initialize(action:)
11
+ @action = action
12
+ super(message)
13
+ end
14
+
15
+ def message
16
+ Decouplio::Const::ErrorMessages::EXECUTION_ERROR
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_error'
4
+ require_relative '../const/validations/pass'
5
+ require_relative '../const/validations/common'
6
+
7
+ module Decouplio
8
+ module Errors
9
+ class StepIsNotDefinedForPassError < Decouplio::Errors::BaseError
10
+ def template
11
+ Decouplio::Const::Validations::Pass::VALIDATION_ERROR_MESSAGE
12
+ end
13
+
14
+ def interpolation_values
15
+ [
16
+ @errored_option,
17
+ format(
18
+ Decouplio::Const::Validations::Common::STEP_IS_NOT_DEFINED,
19
+ @details
20
+ ),
21
+ Decouplio::Const::Validations::Pass::ALLOWED_OPTIONS_MESSAGE,
22
+ Decouplio::Const::Validations::Pass::MANUAL_URL
23
+ ]
24
+ end
25
+ end
26
+ end
27
+ end
@@ -3,6 +3,7 @@
3
3
  require_relative 'flow'
4
4
  require_relative 'const/types'
5
5
  require_relative 'const/doby_aide_options'
6
+ require_relative 'const/step_options'
6
7
  require_relative 'octo_hash_case'
7
8
  require_relative 'errors/options_validation_error'
8
9
  require_relative 'errors/palp_validation_error'
@@ -30,17 +31,61 @@ module Decouplio
30
31
  end
31
32
 
32
33
  def step(stp, **options)
33
- @steps << options.merge(type: Decouplio::Const::Types::STEP_TYPE, name: stp)
34
+ if stp.is_a?(Class) && !(stp < Decouplio::Action)
35
+ step_options = {}
36
+
37
+ options.each_key do |key|
38
+ step_options[key] = options.delete(key) if Decouplio::Const::StepOptions::ALLOWED.include?(key)
39
+ end
40
+
41
+ @steps << {
42
+ type: Decouplio::Const::Types::STEP_TYPE,
43
+ name: stp,
44
+ _args: options,
45
+ **step_options
46
+ }
47
+ else
48
+ @steps << options.merge(type: Decouplio::Const::Types::STEP_TYPE, name: stp)
49
+ end
34
50
  end
35
51
 
36
52
  def fail(stp, **options)
37
53
  raise Decouplio::Errors::FailCanNotBeFirstStepError if @steps.empty?
38
54
 
39
- @steps << options.merge(type: Decouplio::Const::Types::FAIL_TYPE, name: stp)
55
+ if stp.is_a?(Class) && !(stp < Decouplio::Action)
56
+ step_options = {}
57
+ options.each_key do |key|
58
+ step_options[key] = options.delete(key) if Decouplio::Const::StepOptions::ALLOWED.include?(key)
59
+ end
60
+
61
+ @steps << {
62
+ type: Decouplio::Const::Types::FAIL_TYPE,
63
+ name: stp,
64
+ _args: options,
65
+ **step_options
66
+ }
67
+ else
68
+ @steps << options.merge(type: Decouplio::Const::Types::FAIL_TYPE, name: stp)
69
+ end
40
70
  end
41
71
 
42
72
  def pass(stp, **options)
43
- @steps << options.merge(type: Decouplio::Const::Types::PASS_TYPE, name: stp)
73
+ if stp.is_a?(Class) && !(stp < Decouplio::Action)
74
+ step_options = {}
75
+
76
+ options.each_key do |key|
77
+ step_options[key] = options.delete(key) if Decouplio::Const::StepOptions::ALLOWED.include?(key)
78
+ end
79
+
80
+ @steps << {
81
+ type: Decouplio::Const::Types::PASS_TYPE,
82
+ name: stp,
83
+ _args: options,
84
+ **step_options
85
+ }
86
+ else
87
+ @steps << options.merge(type: Decouplio::Const::Types::PASS_TYPE, name: stp)
88
+ end
44
89
  end
45
90
 
46
91
  def octo(octo_name, **options, &block)
@@ -86,6 +131,9 @@ module Decouplio
86
131
  end
87
132
 
88
133
  def doby(doby_class, **options)
134
+ warn(
135
+ 'DEPRECATION WARNING: "doby" step type will be deprecated at alpha8 version. Use "step" or "pass" instead.'
136
+ )
89
137
  step_options = {}
90
138
  options.each_key do |key|
91
139
  step_options[key] = options.delete(key) if Decouplio::Const::DobyAideOptions::ALLOWED.include?(key)
@@ -102,6 +150,7 @@ module Decouplio
102
150
  end
103
151
 
104
152
  def aide(aide_class, **options)
153
+ warn('DEPRECATION WARNING: "aide" step type will be deprecated at alpha8 version. Use "fail" instead.')
105
154
  raise Decouplio::Errors::AideCanNotBeFirstStepError if @steps.empty?
106
155
 
107
156
  step_options = {}
@@ -21,6 +21,7 @@ require_relative 'errors/resq_handler_method_error'
21
21
  require_relative 'errors/step_finish_him_error'
22
22
  require_relative 'errors/step_is_not_defined_for_step_error'
23
23
  require_relative 'errors/step_is_not_defined_for_fail_error'
24
+ require_relative 'errors/step_is_not_defined_for_pass_error'
24
25
  require_relative 'errors/step_is_not_defined_for_wrap_error'
25
26
  require_relative 'errors/step_is_not_defined_for_aide_error'
26
27
  require_relative 'errors/step_is_not_defined_for_doby_error'
@@ -70,7 +71,7 @@ module Decouplio
70
71
  when Decouplio::Const::Types::FAIL_TYPE
71
72
  validate_fail(options: filtered_options, step_names: step_names)
72
73
  when Decouplio::Const::Types::PASS_TYPE
73
- validate_pass(options: filtered_options)
74
+ validate_pass(options: filtered_options, step_names: step_names)
74
75
  when Decouplio::Const::Types::OCTO_TYPE
75
76
  validate_octo(options: filtered_options, hash_case: options[:hash_case])
76
77
  when Decouplio::Const::Types::WRAP_TYPE
@@ -86,7 +87,7 @@ module Decouplio
86
87
  when Decouplio::Const::Types::ACTION_TYPE_PASS
87
88
  validate_action(action_class: options[:action], type: Decouplio::Const::Types::PASS_TYPE)
88
89
  validate_error_store(parent_action_class: @action_class, child_action_class: options[:action])
89
- validate_pass(options: filtered_options)
90
+ validate_pass(options: filtered_options, step_names: step_names)
90
91
  when Decouplio::Const::Types::RESQ_TYPE_STEP,
91
92
  Decouplio::Const::Types::RESQ_TYPE_FAIL,
92
93
  Decouplio::Const::Types::RESQ_TYPE_PASS
@@ -122,7 +123,8 @@ module Decouplio
122
123
  check_fail_finish_him(options: options)
123
124
  end
124
125
 
125
- def validate_pass(options:)
126
+ def validate_pass(options:, step_names:)
127
+ check_step_presence_for_pass(options: options, step_names: step_names)
126
128
  check_pass_extra_keys(options: options)
127
129
  check_pass_finish_him(options: options)
128
130
  end
@@ -174,7 +176,8 @@ module Decouplio
174
176
 
175
177
  def check_step_presence_for_step(options:, step_names:)
176
178
  options.slice(*STEP_CHECK_STEP_PRESENCE).each do |option_key, option_value|
177
- next if %i[on_success on_failure].include?(option_key) && STEP_ALLOWED_ON_S_ON_F_VALUES.include?(option_value)
179
+ next if %i[on_success on_failure on_error].include?(option_key) &&
180
+ STEP_ALLOWED_ON_S_ON_F_VALUES.include?(option_value)
178
181
 
179
182
  next if step_names.keys.include?(option_value)
180
183
 
@@ -185,9 +188,24 @@ module Decouplio
185
188
  end
186
189
  end
187
190
 
191
+ def check_step_presence_for_pass(options:, step_names:)
192
+ options.slice(*PASS_CHECK_STEP_PRESENCE).each do |option_key, option_value|
193
+ next if %i[on_error].include?(option_key) &&
194
+ STEP_ALLOWED_ON_S_ON_F_VALUES.include?(option_value)
195
+
196
+ next if step_names.keys.include?(option_value)
197
+
198
+ raise Decouplio::Errors::StepIsNotDefinedForPassError.new(
199
+ errored_option: options.slice(option_key).to_s,
200
+ details: option_value
201
+ )
202
+ end
203
+ end
204
+
188
205
  def check_step_presence_for_doby(options:, step_names:)
189
206
  options.slice(*STEP_CHECK_STEP_PRESENCE).each do |option_key, option_value|
190
- next if %i[on_success on_failure].include?(option_key) && STEP_ALLOWED_ON_S_ON_F_VALUES.include?(option_value)
207
+ next if %i[on_success on_failure on_error].include?(option_key) &&
208
+ STEP_ALLOWED_ON_S_ON_F_VALUES.include?(option_value)
191
209
 
192
210
  next if step_names.keys.include?(option_value)
193
211
 
@@ -200,7 +218,8 @@ module Decouplio
200
218
 
201
219
  def check_step_presence_for_aide(options:, step_names:)
202
220
  options.slice(*STEP_CHECK_STEP_PRESENCE).each do |option_key, option_value|
203
- next if %i[on_success on_failure].include?(option_key) && STEP_ALLOWED_ON_S_ON_F_VALUES.include?(option_value)
221
+ next if %i[on_success on_failure on_error].include?(option_key) &&
222
+ STEP_ALLOWED_ON_S_ON_F_VALUES.include?(option_value)
204
223
 
205
224
  next if step_names.keys.include?(option_value)
206
225
 
@@ -213,7 +232,8 @@ module Decouplio
213
232
 
214
233
  def check_step_presence_for_fail(options:, step_names:)
215
234
  options.slice(*STEP_CHECK_STEP_PRESENCE).each do |option_key, option_value|
216
- next if %i[on_success on_failure].include?(option_key) && STEP_ALLOWED_ON_S_ON_F_VALUES.include?(option_value)
235
+ next if %i[on_success on_failure on_error].include?(option_key) &&
236
+ STEP_ALLOWED_ON_S_ON_F_VALUES.include?(option_value)
217
237
 
218
238
  next if step_names.keys.include?(option_value)
219
239
 
@@ -226,7 +246,8 @@ module Decouplio
226
246
 
227
247
  def check_step_presence_for_wrap(options:, step_names:)
228
248
  options.slice(*WRAP_CHECK_STEP_PRESENCE).each do |option_key, option_value|
229
- next if %i[on_success on_failure].include?(option_key) && STEP_ALLOWED_ON_S_ON_F_VALUES.include?(option_value)
249
+ next if %i[on_success on_failure on_error].include?(option_key) &&
250
+ STEP_ALLOWED_ON_S_ON_F_VALUES.include?(option_value)
230
251
 
231
252
  next if step_names.keys.include?(option_value)
232
253
 
@@ -546,6 +567,7 @@ module Decouplio
546
567
  hash_case
547
568
  wrap_flow
548
569
  step_to_resq
570
+ _args
549
571
  ].freeze
550
572
 
551
573
  # *************************************************
@@ -555,12 +577,14 @@ module Decouplio
555
577
  STEP_CHECK_METHOD_EXISTENCE_OPTIONS = %i[
556
578
  on_success
557
579
  on_failure
580
+ on_error
558
581
  if
559
582
  unless
560
583
  ].freeze
561
584
  STEP_CHECK_STEP_PRESENCE = %i[
562
585
  on_success
563
586
  on_failure
587
+ on_error
564
588
  ].freeze
565
589
  STEP_ALLOWED_ON_S_ON_F_VALUES = [
566
590
  Decouplio::Const::Results::STEP_PASS,
@@ -570,6 +594,7 @@ module Decouplio
570
594
  STEP_ALLOWED_OPTIONS = %i[
571
595
  on_success
572
596
  on_failure
597
+ on_error
573
598
  finish_him
574
599
  if
575
600
  unless
@@ -578,6 +603,7 @@ module Decouplio
578
603
  ALLOWED_STEP_FINISH_HIM_VALUES = %i[
579
604
  on_success
580
605
  on_failure
606
+ on_error
581
607
  ].freeze
582
608
 
583
609
  # *************************************************
@@ -591,12 +617,13 @@ module Decouplio
591
617
  FAIL_ALLOWED_OPTIONS = %i[
592
618
  on_success
593
619
  on_failure
620
+ on_error
594
621
  finish_him
595
622
  if
596
623
  unless
597
624
  action
598
625
  ].freeze
599
- ALLOWED_FAIL_FINISH_HIM_VALUES = [true, :on_success, :on_failure].freeze
626
+ ALLOWED_FAIL_FINISH_HIM_VALUES = [true, :on_success, :on_failure, :on_error].freeze
600
627
 
601
628
  # *************************************************
602
629
  # PASS
@@ -607,13 +634,17 @@ module Decouplio
607
634
  if
608
635
  unless
609
636
  action
637
+ on_error
610
638
  ].freeze
611
639
 
612
640
  PASS_CHECK_METHOD_EXISTENCE_OPTIONS = %i[
613
641
  if
614
642
  unless
615
643
  ].freeze
616
- ALLOWED_PASS_FINISH_HIM_VALUES = [true].freeze
644
+ PASS_CHECK_STEP_PRESENCE = %i[
645
+ on_error
646
+ ].freeze
647
+ ALLOWED_PASS_FINISH_HIM_VALUES = [true, :on_error].freeze
617
648
 
618
649
  # *************************************************
619
650
  # OCTO
@@ -641,16 +672,19 @@ module Decouplio
641
672
  WRAP_CHECK_METHOD_EXISTENCE_OPTIONS = %i[
642
673
  on_success
643
674
  on_failure
675
+ on_error
644
676
  if
645
677
  unless
646
678
  ].freeze
647
679
  WRAP_CHECK_STEP_PRESENCE = %i[
648
680
  on_success
649
681
  on_failure
682
+ on_error
650
683
  ].freeze
651
684
  WRAP_ALLOWED_OPTIONS = %i[
652
685
  on_success
653
686
  on_failure
687
+ on_error
654
688
  finish_him
655
689
  if
656
690
  unless
@@ -661,6 +695,7 @@ module Decouplio
661
695
  ALLOWED_WRAP_FINISH_HIM_VALUES = %i[
662
696
  on_success
663
697
  on_failure
698
+ on_error
664
699
  ].freeze
665
700
 
666
701
  # *************************************************
@@ -670,6 +705,7 @@ module Decouplio
670
705
  RESQ_NOT_ALLOWED_OPTIONS = %i[
671
706
  on_success
672
707
  on_failure
708
+ on_error
673
709
  finish_him
674
710
  if
675
711
  unless
@@ -5,10 +5,11 @@ require_relative 'base_step'
5
5
  module Decouplio
6
6
  module Steps
7
7
  class BaseResq < BaseStep
8
- def initialize(handler_hash:, step_to_resq:)
8
+ def initialize(handler_hash:, step_to_resq:, on_error_type:)
9
9
  super()
10
10
  @handler_hash = handler_hash
11
11
  @step_to_resq = step_to_resq
12
+ @on_error_type = on_error_type
12
13
  end
13
14
 
14
15
  def process(instance:)
@@ -21,8 +22,17 @@ module Decouplio
21
22
  instance.append_railway_flow(handler_method)
22
23
  instance.public_send(handler_method, e, **instance.ctx)
23
24
 
24
- instance.fail_action
25
- Decouplio::Const::Results::ERROR
25
+ case @on_error_type
26
+ when Decouplio::Const::Results::PASS, Decouplio::Const::Results::STEP_PASS
27
+ instance.pass_action
28
+ Decouplio::Const::Results::ERROR
29
+ when Decouplio::Const::Results::FINISH_HIM
30
+ instance.fail_action
31
+ Decouplio::Const::Results::FINISH_HIM
32
+ else
33
+ instance.fail_action
34
+ Decouplio::Const::Results::ERROR
35
+ end
26
36
  else
27
37
  result
28
38
  end