convenient_service 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -0
  3. data/README.md +1 -1
  4. data/convenient_service.gemspec +24 -5
  5. data/lib/convenient_service/common/plugins/can_have_user_provided_entity/commands/find_or_create_entity.rb +7 -2
  6. data/lib/convenient_service/common/plugins/can_have_user_provided_entity/exceptions.rb +4 -4
  7. data/lib/convenient_service/common/plugins/has_around_callbacks/exceptions.rb +2 -2
  8. data/lib/convenient_service/common/plugins/has_around_callbacks/middleware.rb +2 -2
  9. data/lib/convenient_service/common/plugins/has_instance_proxy/commands/create_instance_proxy_class.rb +83 -0
  10. data/lib/convenient_service/common/plugins/has_instance_proxy/commands.rb +3 -0
  11. data/lib/convenient_service/common/plugins/has_instance_proxy/concern.rb +22 -0
  12. data/lib/convenient_service/common/plugins/has_instance_proxy/entities/instance_proxy.rb +76 -0
  13. data/lib/convenient_service/common/plugins/has_instance_proxy/entities.rb +3 -0
  14. data/lib/convenient_service/common/plugins/has_instance_proxy/middleware.rb +20 -0
  15. data/lib/convenient_service/common/plugins/has_instance_proxy.rb +6 -0
  16. data/lib/convenient_service/common/plugins.rb +1 -0
  17. data/lib/convenient_service/core/concern/class_methods.rb +7 -2
  18. data/lib/convenient_service/core/concern/instance_methods.rb +7 -2
  19. data/lib/convenient_service/core/entities/config/commands/track_method_missing_commit_trigger.rb +1 -1
  20. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/caller/commands/define_method_middlewares_caller.rb +2 -2
  21. data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/middlewares/base/commands/create_observable_middleware.rb +3 -0
  22. data/lib/convenient_service/core/entities/config/exceptions.rb +4 -4
  23. data/lib/convenient_service/core/entities/config.rb +1 -1
  24. data/lib/convenient_service/dependencies/extractions/active_support_backtrace_cleaner/backtrace_cleaner.rb +28 -8
  25. data/lib/convenient_service/dependencies/extractions/active_support_backtrace_cleaner.rb +3 -3
  26. data/lib/convenient_service/dependencies/extractions/b.rb +2 -0
  27. data/lib/convenient_service/dependencies/extractions/ce.rb +16 -0
  28. data/lib/convenient_service/dependencies/extractions.rb +1 -0
  29. data/lib/convenient_service/dependencies.rb +6 -1
  30. data/lib/convenient_service/examples/standard/request_params.rb +0 -1
  31. data/lib/convenient_service/examples/standard/v1/request_params.rb +0 -1
  32. data/lib/convenient_service/exception.rb +98 -10
  33. data/lib/convenient_service/feature/configs/standard.rb +8 -0
  34. data/lib/convenient_service/feature/plugins/can_have_entries/commands/define_entries.rb +49 -0
  35. data/lib/convenient_service/feature/plugins/can_have_entries/commands/define_entry.rb +18 -4
  36. data/lib/convenient_service/feature/plugins/can_have_entries/commands.rb +1 -0
  37. data/lib/convenient_service/feature/plugins/can_have_entries/concern.rb +13 -4
  38. data/lib/convenient_service/feature/plugins/can_have_entries/exceptions.rb +14 -4
  39. data/lib/convenient_service/logger.rb +4 -1
  40. data/lib/convenient_service/rspec/helpers/classes/stub_service/entities/result_spec.rb +0 -8
  41. data/lib/convenient_service/rspec/helpers/classes/wrap_method/entities/wrapped_method.rb +5 -5
  42. data/lib/convenient_service/rspec/helpers/classes/wrap_method/exceptions.rb +2 -2
  43. data/lib/convenient_service/rspec/matchers/classes/results/base/entities/validator/commands/validate_result_step.rb +1 -1
  44. data/lib/convenient_service/rspec/matchers/classes/results/base/exceptions.rb +2 -2
  45. data/lib/convenient_service/rspec/primitive_helpers/classes/ignoring_exception/exceptions.rb +2 -2
  46. data/lib/convenient_service/rspec/primitive_helpers/classes/ignoring_exception.rb +1 -1
  47. data/lib/convenient_service/rspec/primitive_matchers/classes/delegate_to/entities/matcher/entities/chainings/sub_matchers/arguments/commands/apply_stub_to_track_delegations.rb +4 -0
  48. data/lib/convenient_service/rspec/primitive_matchers/classes/delegate_to/entities/matcher/entities/chainings_collection/exceptions.rb +7 -7
  49. data/lib/convenient_service/rspec/primitive_matchers/classes/delegate_to/entities/matcher/entities/chainings_collection.rb +3 -3
  50. data/lib/convenient_service/service/plugins/can_have_fallbacks/concern.rb +2 -2
  51. data/lib/convenient_service/service/plugins/can_have_fallbacks/exceptions.rb +4 -4
  52. data/lib/convenient_service/service/plugins/can_have_fallbacks/middleware.rb +1 -1
  53. data/lib/convenient_service/service/plugins/can_have_steps/concern.rb +3 -3
  54. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/commands/define_method_in_container.rb +2 -2
  55. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/concern/instance_methods.rb +1 -1
  56. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/entities/callers/alias.rb +2 -2
  57. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/entities/callers/proc.rb +1 -1
  58. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/entities/callers/raw.rb +1 -1
  59. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/entities/callers/reassignment.rb +2 -2
  60. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/entities/callers/usual.rb +2 -2
  61. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/entities/directions/input.rb +2 -2
  62. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/entities/directions/output.rb +1 -1
  63. data/lib/convenient_service/service/plugins/can_have_steps/entities/method/exceptions.rb +26 -26
  64. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/concern/instance_methods.rb +1 -1
  65. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/exceptions.rb +2 -2
  66. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/can_be_result_step/can_be_executed/exceptions.rb +2 -2
  67. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/can_be_result_step/can_be_executed/middleware.rb +1 -1
  68. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/raises_on_not_result_return_value/exceptions.rb +2 -2
  69. data/lib/convenient_service/service/plugins/can_have_steps/entities/step/plugins/raises_on_not_result_return_value/middleware.rb +1 -1
  70. data/lib/convenient_service/service/plugins/has_inspect/concern.rb +0 -1
  71. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/concern/instance_methods.rb +7 -0
  72. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/data/concern/instance_methods.rb +1 -1
  73. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/entities/status/concern/instance_methods.rb +14 -0
  74. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/has_j_send_status_and_attributes/exceptions.rb +2 -2
  75. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/raises_on_not_checked_result_status/exceptions.rb +2 -2
  76. data/lib/convenient_service/service/plugins/has_j_send_result/entities/result/plugins/raises_on_not_checked_result_status/middleware.rb +1 -1
  77. data/lib/convenient_service/service/plugins/has_j_send_result/exceptions.rb +2 -2
  78. data/lib/convenient_service/service/plugins/has_j_send_result.rb +39 -0
  79. data/lib/convenient_service/service/plugins/has_j_send_result_short_syntax/error/exceptions.rb +6 -6
  80. data/lib/convenient_service/service/plugins/has_j_send_result_short_syntax/error/middleware.rb +3 -3
  81. data/lib/convenient_service/service/plugins/has_j_send_result_short_syntax/failure/exceptions.rb +6 -6
  82. data/lib/convenient_service/service/plugins/has_j_send_result_short_syntax/failure/middleware.rb +3 -3
  83. data/lib/convenient_service/service/plugins/has_j_send_result_short_syntax/success/commands/refute_kwargs_contain_j_send_and_extra_keys.rb +1 -1
  84. data/lib/convenient_service/service/plugins/has_j_send_result_short_syntax/success/exceptions.rb +2 -2
  85. data/lib/convenient_service/service/plugins/has_j_send_result_status_check_short_syntax/concern.rb +0 -8
  86. data/lib/convenient_service/service/plugins/has_result/concern.rb +1 -1
  87. data/lib/convenient_service/service/plugins/has_result/exceptions.rb +2 -2
  88. data/lib/convenient_service/service/plugins/raises_on_double_result/exceptions.rb +2 -2
  89. data/lib/convenient_service/service/plugins/raises_on_double_result/middleware.rb +1 -1
  90. data/lib/convenient_service/service/plugins/raises_on_not_result_return_value/exceptions.rb +2 -2
  91. data/lib/convenient_service/service/plugins/raises_on_not_result_return_value/middleware.rb +1 -1
  92. data/lib/convenient_service/support/abstract_method/exceptions.rb +2 -2
  93. data/lib/convenient_service/support/abstract_method.rb +1 -1
  94. data/lib/convenient_service/support/backtrace_cleaner.rb +123 -0
  95. data/lib/convenient_service/support/cache/exceptions.rb +2 -2
  96. data/lib/convenient_service/support/cache.rb +1 -1
  97. data/lib/convenient_service/support/castable/exceptions.rb +4 -4
  98. data/lib/convenient_service/support/castable.rb +1 -1
  99. data/lib/convenient_service/support/command.rb +3 -3
  100. data/lib/convenient_service/support/counter.rb +6 -6
  101. data/lib/convenient_service/support/dependency_container/commands/assert_valid_container.rb +1 -1
  102. data/lib/convenient_service/support/dependency_container/commands/assert_valid_method.rb +1 -1
  103. data/lib/convenient_service/support/dependency_container/commands/assert_valid_scope.rb +1 -1
  104. data/lib/convenient_service/support/dependency_container/exceptions.rb +8 -8
  105. data/lib/convenient_service/support/dependency_container/export.rb +1 -1
  106. data/lib/convenient_service/support/finite_loop.rb +6 -6
  107. data/lib/convenient_service/support.rb +1 -0
  108. data/lib/convenient_service/utils/array/exceptions.rb +2 -2
  109. data/lib/convenient_service/utils/array/merge.rb +1 -1
  110. data/lib/convenient_service/utils/hash/assert_valid_keys.rb +1 -1
  111. data/lib/convenient_service/version.rb +1 -1
  112. data/lib/convenient_service.rb +98 -0
  113. metadata +22 -41
  114. data/lib/convenient_service/examples/standard/v1/gemfile/services/print_shell_command.rb +0 -47
@@ -126,6 +126,20 @@ module ConvenientService
126
126
  def to_sym
127
127
  @to_sym ||= value.to_sym
128
128
  end
129
+
130
+ ##
131
+ # @return [Boolean, nil]
132
+ #
133
+ def to_bool
134
+ return @to_bool if defined? @to_bool
135
+
136
+ @to_bool =
137
+ case value
138
+ when :success then true
139
+ when :failure then false
140
+ when :error then nil
141
+ end
142
+ end
129
143
  end
130
144
  end
131
145
  end
@@ -14,12 +14,12 @@ module ConvenientService
14
14
  # @param attribute [Symbol]
15
15
  # @return [void]
16
16
  #
17
- def initialize(attribute:)
17
+ def initialize_with_kwargs(attribute:)
18
18
  message = <<~TEXT
19
19
  Data attribute `#{attribute}` does NOT exist. Make sure the corresponding result returns it.
20
20
  TEXT
21
21
 
22
- super(message)
22
+ initialize(message)
23
23
  end
24
24
  end
25
25
  end
@@ -10,14 +10,14 @@ module ConvenientService
10
10
  module RaisesOnNotCheckedResultStatus
11
11
  module Exceptions
12
12
  class StatusIsNotChecked < ::ConvenientService::Exception
13
- def initialize(attribute:)
13
+ def initialize_with_kwargs(attribute:)
14
14
  message = <<~TEXT
15
15
  Attribute `#{attribute}` is accessed before result status is checked.
16
16
 
17
17
  Did you forget to call `success?`, `failure?`, or `error?` on result?
18
18
  TEXT
19
19
 
20
- super(message)
20
+ initialize(message)
21
21
  end
22
22
  end
23
23
  end
@@ -34,7 +34,7 @@ module ConvenientService
34
34
  def assert_has_checked_status!
35
35
  return if entity.internals.cache.exist?(:has_checked_status)
36
36
 
37
- raise Exceptions::StatusIsNotChecked.new(attribute: method)
37
+ ::ConvenientService.raise Exceptions::StatusIsNotChecked.new(attribute: method)
38
38
  end
39
39
  end
40
40
  end
@@ -6,12 +6,12 @@ module ConvenientService
6
6
  module HasJSendResult
7
7
  module Exceptions
8
8
  class ResultIsNotOverridden < ::ConvenientService::Exception
9
- def initialize(service:)
9
+ def initialize_with_kwargs(service:)
10
10
  message = <<~TEXT
11
11
  Result method (#result) of `#{service.class}` is NOT overridden.
12
12
  TEXT
13
13
 
14
- super(message)
14
+ initialize(message)
15
15
  end
16
16
  end
17
17
  end
@@ -6,3 +6,42 @@ require_relative "has_j_send_result/container"
6
6
  require_relative "has_j_send_result/commands"
7
7
  require_relative "has_j_send_result/entities"
8
8
  require_relative "has_j_send_result/exceptions"
9
+
10
+ module ConvenientService
11
+ module Service
12
+ module Plugins
13
+ module HasJSendResult
14
+ class << self
15
+ ##
16
+ # Checks whether an object is a result instance.
17
+ #
18
+ # @api public
19
+ #
20
+ # @param result [Object] Can be any type.
21
+ # @return [Boolean]
22
+ #
23
+ # @example Simple usage.
24
+ # class Service
25
+ # include ConvenientService::Standard::Config
26
+ #
27
+ # def result
28
+ # success
29
+ # end
30
+ # end
31
+ #
32
+ # result = Service.result
33
+ #
34
+ # ConvenientService::Plugins::Service::HasJSendResult.result?(result)
35
+ # # => true
36
+ #
37
+ # ConvenientService::Plugins::Service::HasJSendResult.result?(42)
38
+ # # => false
39
+ #
40
+ def result?(result)
41
+ Commands::IsResult[result: result]
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -10,7 +10,7 @@ module ConvenientService
10
10
  ##
11
11
  # @return [void]
12
12
  #
13
- def initialize
13
+ def initialize_without_arguments
14
14
  message = <<~TEXT
15
15
  Both `args` and `kwargs` are passed to the `error` method.
16
16
 
@@ -23,7 +23,7 @@ module ConvenientService
23
23
  error(message: "Helpful text", code: :descriptive_code)
24
24
  TEXT
25
25
 
26
- super(message)
26
+ initialize(message)
27
27
  end
28
28
  end
29
29
 
@@ -31,7 +31,7 @@ module ConvenientService
31
31
  ##
32
32
  # @return [void]
33
33
  #
34
- def initialize
34
+ def initialize_without_arguments
35
35
  message = <<~TEXT
36
36
  `kwargs` passed to `error` method contain JSend keys and extra keys. That's NOT allowed.
37
37
 
@@ -61,12 +61,12 @@ module ConvenientService
61
61
  error(data: {foo: :bar}, message: "foo", code: :foo)
62
62
  TEXT
63
63
 
64
- super(message)
64
+ initialize(message)
65
65
  end
66
66
  end
67
67
 
68
68
  class MoreThanTwoArgsArePassed < ::ConvenientService::Exception
69
- def initialize
69
+ def initialize_without_arguments
70
70
  message = <<~TEXT
71
71
  More than two `args` are passed to the `error` method.
72
72
 
@@ -76,7 +76,7 @@ module ConvenientService
76
76
  error("Helpful text", :descriptive_code)
77
77
  TEXT
78
78
 
79
- super(message)
79
+ initialize(message)
80
80
  end
81
81
  end
82
82
  end
@@ -15,7 +15,7 @@ module ConvenientService
15
15
  # @return [ConvenientService::Service::Plugins::HasJSendResult::Entities::Result]
16
16
  #
17
17
  def next(*args, **kwargs, &block)
18
- raise Exceptions::BothArgsAndKwargsArePassed.new if args.any? && kwargs.any?
18
+ ::ConvenientService.raise Exceptions::BothArgsAndKwargsArePassed.new if args.any? && kwargs.any?
19
19
 
20
20
  args.any? ? error_from_args : error_from_kwargs
21
21
  end
@@ -31,7 +31,7 @@ module ConvenientService
31
31
  when 1 then chain.next(message: next_arguments.args[0])
32
32
  when 2 then chain.next(message: next_arguments.args[0], code: next_arguments.args[1])
33
33
  else
34
- raise Exceptions::MoreThanTwoArgsArePassed.new
34
+ ::ConvenientService.raise Exceptions::MoreThanTwoArgsArePassed.new
35
35
  end
36
36
  end
37
37
 
@@ -44,7 +44,7 @@ module ConvenientService
44
44
  def error_from_kwargs
45
45
  return chain.next(data: next_arguments.kwargs) if [:data, :message, :code].none? { |key| next_arguments.kwargs.has_key?(key) }
46
46
 
47
- raise Exceptions::KwargsContainJSendAndExtraKeys.new if next_arguments.kwargs.keys.difference([:data, :message, :code]).any?
47
+ ::ConvenientService.raise Exceptions::KwargsContainJSendAndExtraKeys.new if next_arguments.kwargs.keys.difference([:data, :message, :code]).any?
48
48
 
49
49
  chain.next(**next_arguments.kwargs)
50
50
  end
@@ -10,7 +10,7 @@ module ConvenientService
10
10
  ##
11
11
  # @return [void]
12
12
  #
13
- def initialize
13
+ def initialize_without_arguments
14
14
  message = <<~TEXT
15
15
  `kwargs` passed to `failure` method contain JSend keys and extra keys. That's NOT allowed.
16
16
 
@@ -40,7 +40,7 @@ module ConvenientService
40
40
  failure(data: {foo: :bar}, message: "foo", code: :foo)
41
41
  TEXT
42
42
 
43
- super(message)
43
+ initialize(message)
44
44
  end
45
45
  end
46
46
 
@@ -48,7 +48,7 @@ module ConvenientService
48
48
  ##
49
49
  # @return [void]
50
50
  #
51
- def initialize
51
+ def initialize_without_arguments
52
52
  message = <<~TEXT
53
53
  Both `args` and `kwargs` are passed to the `failure` method.
54
54
 
@@ -61,7 +61,7 @@ module ConvenientService
61
61
  failure(message: "Helpful text", code: :descriptive_code)
62
62
  TEXT
63
63
 
64
- super(message)
64
+ initialize(message)
65
65
  end
66
66
  end
67
67
 
@@ -69,7 +69,7 @@ module ConvenientService
69
69
  ##
70
70
  # @return [void]
71
71
  #
72
- def initialize
72
+ def initialize_without_arguments
73
73
  message = <<~TEXT
74
74
  More than two `args` are passed to the `failure` method.
75
75
 
@@ -79,7 +79,7 @@ module ConvenientService
79
79
  failure("Helpful text", :descriptive_code)
80
80
  TEXT
81
81
 
82
- super(message)
82
+ initialize(message)
83
83
  end
84
84
  end
85
85
  end
@@ -15,7 +15,7 @@ module ConvenientService
15
15
  # @return [ConvenientService::Service::Plugins::HasJSendResult::Entities::Result]
16
16
  #
17
17
  def next(*args, **kwargs, &block)
18
- raise Exceptions::BothArgsAndKwargsArePassed.new if args.any? && kwargs.any?
18
+ ::ConvenientService.raise Exceptions::BothArgsAndKwargsArePassed.new if args.any? && kwargs.any?
19
19
 
20
20
  args.any? ? failure_from_args : failure_from_kwargs
21
21
  end
@@ -31,7 +31,7 @@ module ConvenientService
31
31
  when 1 then chain.next(message: next_arguments.args[0])
32
32
  when 2 then chain.next(message: next_arguments.args[0], code: next_arguments.args[1])
33
33
  else
34
- raise Exceptions::MoreThanTwoArgsArePassed.new
34
+ ::ConvenientService.raise Exceptions::MoreThanTwoArgsArePassed.new
35
35
  end
36
36
  end
37
37
 
@@ -44,7 +44,7 @@ module ConvenientService
44
44
  def failure_from_kwargs
45
45
  return chain.next(data: next_arguments.kwargs) if [:data, :message, :code].none? { |key| next_arguments.kwargs.has_key?(key) }
46
46
 
47
- raise Exceptions::KwargsContainJSendAndExtraKeys.new if next_arguments.kwargs.keys.difference([:data, :message, :code]).any?
47
+ ::ConvenientService.raise Exceptions::KwargsContainJSendAndExtraKeys.new if next_arguments.kwargs.keys.difference([:data, :message, :code]).any?
48
48
 
49
49
  chain.next(**next_arguments.kwargs)
50
50
  end
@@ -56,7 +56,7 @@ module ConvenientService
56
56
 
57
57
  return if kwargs.keys.difference([:data, :message, :code]).none?
58
58
 
59
- raise Exceptions::KwargsContainJSendAndExtraKeys.new
59
+ ::ConvenientService.raise Exceptions::KwargsContainJSendAndExtraKeys.new
60
60
  end
61
61
  end
62
62
  end
@@ -10,7 +10,7 @@ module ConvenientService
10
10
  ##
11
11
  # @return [void]
12
12
  #
13
- def initialize
13
+ def initialize_without_arguments
14
14
  message = <<~TEXT
15
15
  `kwargs` passed to `success` method contain JSend keys and extra keys. That's NOT allowed.
16
16
 
@@ -30,7 +30,7 @@ module ConvenientService
30
30
  success(code: :foo)
31
31
  TEXT
32
32
 
33
- super(message)
33
+ initialize(message)
34
34
  end
35
35
  end
36
36
  end
@@ -10,7 +10,6 @@ module ConvenientService
10
10
  class_methods do
11
11
  ##
12
12
  # @return [Boolean]
13
- # @since 0.2.0
14
13
  #
15
14
  def success?(...)
16
15
  result(...).success?
@@ -18,7 +17,6 @@ module ConvenientService
18
17
 
19
18
  ##
20
19
  # @return [Boolean]
21
- # @since 0.2.0
22
20
  #
23
21
  def error?(...)
24
22
  result(...).error?
@@ -26,7 +24,6 @@ module ConvenientService
26
24
 
27
25
  ##
28
26
  # @return [Boolean]
29
- # @since 0.2.0
30
27
  #
31
28
  def failure?(...)
32
29
  result(...).failure?
@@ -34,7 +31,6 @@ module ConvenientService
34
31
 
35
32
  ##
36
33
  # @return [Boolean]
37
- # @since 0.2.0
38
34
  #
39
35
  def not_success?(...)
40
36
  result(...).not_success?
@@ -42,7 +38,6 @@ module ConvenientService
42
38
 
43
39
  ##
44
40
  # @return [Boolean]
45
- # @since 0.2.0
46
41
  #
47
42
  def not_error?(...)
48
43
  result(...).not_error?
@@ -50,7 +45,6 @@ module ConvenientService
50
45
 
51
46
  ##
52
47
  # @return [Boolean]
53
- # @since 0.2.0
54
48
  #
55
49
  def not_failure?(...)
56
50
  result(...).not_failure?
@@ -58,7 +52,6 @@ module ConvenientService
58
52
 
59
53
  ##
60
54
  # @return [Boolean]
61
- # @since 0.12.0
62
55
  #
63
56
  def ok?(...)
64
57
  result(...).success?
@@ -66,7 +59,6 @@ module ConvenientService
66
59
 
67
60
  ##
68
61
  # @return [Boolean]
69
- # @since 0.12.0
70
62
  #
71
63
  def not_ok?(...)
72
64
  result(...).not_success?
@@ -23,7 +23,7 @@ module ConvenientService
23
23
  # @raise [ConvenientService::Service::Plugins::HasResult::Exceptions::ResultIsNotOverridden]
24
24
  #
25
25
  def result
26
- raise Exceptions::ResultIsNotOverridden.new(service: self)
26
+ ::ConvenientService.raise Exceptions::ResultIsNotOverridden.new(service: self)
27
27
  end
28
28
  end
29
29
  end
@@ -6,12 +6,12 @@ module ConvenientService
6
6
  module HasResult
7
7
  module Exceptions
8
8
  class ResultIsNotOverridden < ::ConvenientService::Exception
9
- def initialize(service:)
9
+ def initialize_with_kwargs(service:)
10
10
  message = <<~TEXT
11
11
  Result method (#result) of `#{service.class}` is NOT overridden.
12
12
  TEXT
13
13
 
14
- super(message)
14
+ initialize(message)
15
15
  end
16
16
  end
17
17
  end
@@ -6,7 +6,7 @@ module ConvenientService
6
6
  module RaisesOnDoubleResult
7
7
  module Exceptions
8
8
  class DoubleResult < ::ConvenientService::Exception
9
- def initialize(service:)
9
+ def initialize_with_kwargs(service:)
10
10
  message = <<~TEXT
11
11
  `#{service.class}` service has a double result.
12
12
 
@@ -24,7 +24,7 @@ module ConvenientService
24
24
  end
25
25
  TEXT
26
26
 
27
- super(message)
27
+ initialize(message)
28
28
  end
29
29
  end
30
30
  end
@@ -48,7 +48,7 @@ module ConvenientService
48
48
  def refute_has_j_send_result!
49
49
  return unless entity.internals.cache.exist?(:has_j_send_result)
50
50
 
51
- raise Exceptions::DoubleResult.new(service: entity)
51
+ ::ConvenientService.raise Exceptions::DoubleResult.new(service: entity)
52
52
  end
53
53
 
54
54
  ##
@@ -6,7 +6,7 @@ module ConvenientService
6
6
  module RaisesOnNotResultReturnValue
7
7
  module Exceptions
8
8
  class ReturnValueNotKindOfResult < ::ConvenientService::Exception
9
- def initialize(service:, result:, method:)
9
+ def initialize_with_kwargs(service:, result:, method:)
10
10
  message = <<~TEXT
11
11
  Return value of service `#{service.class}` is NOT a `Result`.
12
12
  It is `#{result.class}`.
@@ -14,7 +14,7 @@ module ConvenientService
14
14
  Did you forget to call `success`, `failure`, or `error` from the `:#{method}` method?
15
15
  TEXT
16
16
 
17
- super(message)
17
+ initialize(message)
18
18
  end
19
19
  end
20
20
  end
@@ -16,7 +16,7 @@ module ConvenientService
16
16
 
17
17
  return original_result if commands.is_result?(original_result)
18
18
 
19
- raise Exceptions::ReturnValueNotKindOfResult.new(service: entity, result: original_result, method: method)
19
+ ::ConvenientService.raise Exceptions::ReturnValueNotKindOfResult.new(service: entity, result: original_result, method: method)
20
20
  end
21
21
  end
22
22
  end
@@ -5,7 +5,7 @@ module ConvenientService
5
5
  module AbstractMethod
6
6
  module Exceptions
7
7
  class AbstractMethodNotOverridden < ::ConvenientService::Exception
8
- def initialize(instance:, method:)
8
+ def initialize_with_kwargs(instance:, method:)
9
9
  klass = instance.is_a?(::Class) ? instance : instance.class
10
10
  method_type = Utils::Object.resolve_type(instance)
11
11
 
@@ -13,7 +13,7 @@ module ConvenientService
13
13
  `#{klass}` should implement abstract #{method_type} method `#{method}`.
14
14
  TEXT
15
15
 
16
- super(message)
16
+ initialize(message)
17
17
  end
18
18
  end
19
19
  end
@@ -11,7 +11,7 @@ module ConvenientService
11
11
  def abstract_method(*names)
12
12
  names.each do |name|
13
13
  define_method(name) do |*args, **kwargs, &block|
14
- raise Exceptions::AbstractMethodNotOverridden.new(instance: self, method: name)
14
+ ::ConvenientService.raise Exceptions::AbstractMethodNotOverridden.new(instance: self, method: name)
15
15
  end
16
16
  end
17
17
  end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # @note Other gems are also trying to integrate with Rails Backtrace Cleaner.
5
+ # @see https://github.com/sidekiq/sidekiq/pull/5796
6
+ # @see https://github.com/sidekiq/sidekiq/issues/5589
7
+ # @see https://github.com/appsignal/appsignal-ruby/issues/380
8
+ #
9
+ module ConvenientService
10
+ module Support
11
+ ##
12
+ # Rails v7.1.2 Backtrace Cleaner descendant.
13
+ # Has Convenient Service specific silencer - `add_convenient_service_silencer`.
14
+ # By default, it uses only `add_stdlib_silencer` and `add_convenient_service_silencer`.
15
+ #
16
+ # @see https://api.rubyonrails.org/classes/ActiveSupport/BacktraceCleaner.html
17
+ # @see https://medium.com/one-medical-technology/filtering-ruby-backtraces-for-debugging-4df75133ab71
18
+ # @see https://twitter.com/websebdev/status/1375831554518360065?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1375831554518360065%7Ctwgr%5E459595174e71c0f1aa3826c89f2ffca0c3da6ea3%7Ctwcon%5Es1_&ref_url=https%3A%2F%2Fwww.redditmedia.com%2Fmediaembed%2Fmegii9%2F%3Fresponsive%3Dtrueis_nightmode%3Dtrue
19
+ # @see https://stackoverflow.com/questions/22727219/using-backtracecleaner-in-rails-console
20
+ #
21
+ class BacktraceCleaner < Dependencies::Extractions::ActiveSupportBacktraceCleaner::BacktraceCleaner
22
+ ##
23
+ # @return [void]
24
+ #
25
+ # @note `ConvenientService::Support::BacktraceCleaner` intentionally does NOT exclude external gems lines from backtrace.
26
+ #
27
+ # @see https://api.rubyonrails.org/classes/ActiveSupport/BacktraceCleaner.html
28
+ # @see https://github.com/rails/rails/blob/v7.1.2/activesupport/lib/active_support/backtrace_cleaner.rb#L34
29
+ #
30
+ # @internal
31
+ # IMPORTANT: Convenient Service integrates with external gems.
32
+ # This means that external gems exceptions should NOT be considered as Convenient Service internal exceptions.
33
+ #
34
+ def initialize(...)
35
+ super
36
+
37
+ remove_filters!
38
+ remove_silencers!
39
+
40
+ ##
41
+ # NOTE: Uses `::RbConfig` to resolve stdlib directory.
42
+ # - https://idiosyncratic-ruby.com/42-ruby-config.html
43
+ # - https://github.com/ruby/ruby/blob/master/tool/mkconfig.rb
44
+ #
45
+ add_stdlib_silencer
46
+
47
+ ##
48
+ # NOTE:
49
+ #
50
+ add_convenient_service_silencer
51
+ end
52
+
53
+ ##
54
+ # @note `add_gem_filter` is made public to have a way to bring back Rails Backtrace Cleaner default behavior if necessary.
55
+ #
56
+ # @return [void]
57
+ #
58
+ # @see https://github.com/rails/rails/blob/v7.1.2/activesupport/lib/active_support/backtrace_cleaner.rb#L110
59
+ #
60
+ public :add_gem_filter
61
+
62
+ ##
63
+ # @note `add_gem_silencer` is made public to have a way to bring back Rails Backtrace Cleaner default behavior if necessary.
64
+ #
65
+ # @return [void]
66
+ #
67
+ # @see https://github.com/rails/rails/blob/v7.1.2/activesupport/lib/active_support/backtrace_cleaner.rb#L119
68
+ #
69
+ public :add_gem_silencer
70
+
71
+ ##
72
+ # @note `add_stdlib_silencer` is made public to allow the end-user to adjust clean in any way.
73
+ #
74
+ # @return [void]
75
+ #
76
+ # @see https://github.com/rails/rails/blob/v7.1.2/activesupport/lib/active_support/backtrace_cleaner.rb#L123
77
+ #
78
+ public :add_stdlib_silencer
79
+
80
+ ##
81
+ # Since Convenient Service is using middleware chains under the hood, exception backtraces may be huge.
82
+ # As a consequence, it takes too much time during the debugging process to find the application line of code that causes the exception.
83
+ # This silencer removes all Convenient Service lines from backtraces.
84
+ #
85
+ # @note To bring back Convenient Service lines to backtraces, use the `remove_silencers` or check the `CleansExceptionBacktrace` plugin.
86
+ #
87
+ # @return [void]
88
+ #
89
+ def add_convenient_service_silencer
90
+ add_silencer { |line| line.start_with?(::ConvenientService.root.to_s) && !line.start_with?(::ConvenientService.examples_root.to_s) }
91
+ end
92
+
93
+ ##
94
+ # Works exactly in the same way as the original `clean`, except it falls back to the original backtrace in case of any exceptions inside filters or silencers.
95
+ # Also returns an empty array, when `backtrace` is `nil`.
96
+ #
97
+ # @return [Array<String>]
98
+ #
99
+ # @see https://api.rubyonrails.org/classes/ActiveSupport/BacktraceCleaner.html#method-i-clean
100
+ #
101
+ # @internal
102
+ # IMPORTANT: Sometimes `exception.backtrace` can be `nil`.
103
+ # - https://blog.kalina.tech/2019/04/exception-without-backtrace-in-ruby.html
104
+ # - https://github.com/jruby/jruby/issues/4467
105
+ #
106
+ def clean(backtrace, *args)
107
+ if backtrace.nil?
108
+ ::ConvenientService.logger.warn { "[BacktraceCleaner] `nil` backtrace | Empty array is used as fallback" }
109
+
110
+ return []
111
+ end
112
+
113
+ begin
114
+ super
115
+ rescue
116
+ ::ConvenientService.logger.warn { "[BacktraceCleaner] Some filter or silencer is broken | Original backtrace is used as fallback" }
117
+
118
+ backtrace
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -9,14 +9,14 @@ module ConvenientService
9
9
  # @param backend [Symbol]
10
10
  # @return [void]
11
11
  #
12
- def initialize(backend:)
12
+ def initialize_with_kwargs(backend:)
13
13
  message = <<~TEXT
14
14
  Backend `#{backend}` is NOT supported.
15
15
 
16
16
  Supported backends are #{printable_backends}.
17
17
  TEXT
18
18
 
19
- super(message)
19
+ initialize(message)
20
20
  end
21
21
 
22
22
  private
@@ -21,7 +21,7 @@ module ConvenientService
21
21
  when Constants::Backends::THREAD_SAFE_ARRAY
22
22
  Entities::Caches::ThreadSafeArray.new
23
23
  else
24
- raise Exceptions::NotSupportedBackend.new(backend: backend)
24
+ ::ConvenientService.raise Exceptions::NotSupportedBackend.new(backend: backend)
25
25
  end
26
26
  end
27
27
  end
@@ -5,22 +5,22 @@ module ConvenientService
5
5
  module Castable
6
6
  module Exceptions
7
7
  class CastIsNotOverridden < ::ConvenientService::Exception
8
- def initialize(klass:)
8
+ def initialize_with_kwargs(klass:)
9
9
  message = <<~TEXT
10
10
  Cast method (.cast) of `#{klass}` is NOT overridden.
11
11
  TEXT
12
12
 
13
- super(message)
13
+ initialize(message)
14
14
  end
15
15
  end
16
16
 
17
17
  class FailedToCast < ::ConvenientService::Exception
18
- def initialize(other:, klass:)
18
+ def initialize_with_kwargs(other:, klass:)
19
19
  message = <<~TEXT
20
20
  Failed to cast `#{other.inspect}` into `#{klass}`.
21
21
  TEXT
22
22
 
23
- super(message)
23
+ initialize(message)
24
24
  end
25
25
  end
26
26
  end