cmdx 1.0.1 → 1.1.0

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 (157) hide show
  1. checksums.yaml +4 -4
  2. data/.cursor/prompts/rspec.md +20 -0
  3. data/.cursor/prompts/yardoc.md +8 -0
  4. data/.rubocop.yml +2 -0
  5. data/CHANGELOG.md +17 -2
  6. data/README.md +1 -1
  7. data/docs/basics/call.md +2 -2
  8. data/docs/basics/chain.md +1 -1
  9. data/docs/callbacks.md +3 -36
  10. data/docs/configuration.md +58 -12
  11. data/docs/interruptions/exceptions.md +1 -1
  12. data/docs/interruptions/faults.md +2 -2
  13. data/docs/logging.md +4 -4
  14. data/docs/middlewares.md +43 -43
  15. data/docs/parameters/coercions.md +49 -38
  16. data/docs/parameters/defaults.md +1 -1
  17. data/docs/parameters/validations.md +0 -39
  18. data/docs/testing.md +11 -12
  19. data/docs/workflows.md +4 -4
  20. data/lib/cmdx/.DS_Store +0 -0
  21. data/lib/cmdx/callback.rb +36 -56
  22. data/lib/cmdx/callback_registry.rb +82 -73
  23. data/lib/cmdx/chain.rb +65 -122
  24. data/lib/cmdx/chain_inspector.rb +22 -115
  25. data/lib/cmdx/chain_serializer.rb +17 -148
  26. data/lib/cmdx/coercion.rb +49 -0
  27. data/lib/cmdx/coercion_registry.rb +94 -0
  28. data/lib/cmdx/coercions/array.rb +18 -36
  29. data/lib/cmdx/coercions/big_decimal.rb +21 -33
  30. data/lib/cmdx/coercions/boolean.rb +21 -40
  31. data/lib/cmdx/coercions/complex.rb +18 -31
  32. data/lib/cmdx/coercions/date.rb +20 -39
  33. data/lib/cmdx/coercions/date_time.rb +22 -39
  34. data/lib/cmdx/coercions/float.rb +19 -32
  35. data/lib/cmdx/coercions/hash.rb +22 -41
  36. data/lib/cmdx/coercions/integer.rb +20 -33
  37. data/lib/cmdx/coercions/rational.rb +20 -32
  38. data/lib/cmdx/coercions/string.rb +23 -31
  39. data/lib/cmdx/coercions/time.rb +24 -40
  40. data/lib/cmdx/coercions/virtual.rb +14 -31
  41. data/lib/cmdx/configuration.rb +57 -171
  42. data/lib/cmdx/context.rb +22 -165
  43. data/lib/cmdx/core_ext/hash.rb +42 -67
  44. data/lib/cmdx/core_ext/module.rb +35 -79
  45. data/lib/cmdx/core_ext/object.rb +63 -98
  46. data/lib/cmdx/correlator.rb +40 -156
  47. data/lib/cmdx/error.rb +37 -202
  48. data/lib/cmdx/errors.rb +165 -202
  49. data/lib/cmdx/fault.rb +55 -158
  50. data/lib/cmdx/faults.rb +26 -137
  51. data/lib/cmdx/immutator.rb +22 -109
  52. data/lib/cmdx/lazy_struct.rb +103 -187
  53. data/lib/cmdx/log_formatters/json.rb +14 -40
  54. data/lib/cmdx/log_formatters/key_value.rb +14 -40
  55. data/lib/cmdx/log_formatters/line.rb +14 -48
  56. data/lib/cmdx/log_formatters/logstash.rb +14 -57
  57. data/lib/cmdx/log_formatters/pretty_json.rb +14 -50
  58. data/lib/cmdx/log_formatters/pretty_key_value.rb +13 -46
  59. data/lib/cmdx/log_formatters/pretty_line.rb +16 -54
  60. data/lib/cmdx/log_formatters/raw.rb +19 -49
  61. data/lib/cmdx/logger.rb +20 -82
  62. data/lib/cmdx/logger_ansi.rb +18 -75
  63. data/lib/cmdx/logger_serializer.rb +24 -114
  64. data/lib/cmdx/middleware.rb +38 -60
  65. data/lib/cmdx/middleware_registry.rb +81 -77
  66. data/lib/cmdx/middlewares/correlate.rb +41 -226
  67. data/lib/cmdx/middlewares/timeout.rb +46 -185
  68. data/lib/cmdx/parameter.rb +120 -198
  69. data/lib/cmdx/parameter_evaluator.rb +231 -0
  70. data/lib/cmdx/parameter_inspector.rb +25 -56
  71. data/lib/cmdx/parameter_registry.rb +59 -84
  72. data/lib/cmdx/parameter_serializer.rb +23 -74
  73. data/lib/cmdx/railtie.rb +24 -107
  74. data/lib/cmdx/result.rb +254 -260
  75. data/lib/cmdx/result_ansi.rb +19 -85
  76. data/lib/cmdx/result_inspector.rb +27 -68
  77. data/lib/cmdx/result_logger.rb +18 -81
  78. data/lib/cmdx/result_serializer.rb +28 -132
  79. data/lib/cmdx/rspec/matchers.rb +28 -0
  80. data/lib/cmdx/rspec/result_matchers/be_executed.rb +42 -0
  81. data/lib/cmdx/rspec/result_matchers/be_failed_task.rb +94 -0
  82. data/lib/cmdx/rspec/result_matchers/be_skipped_task.rb +94 -0
  83. data/lib/cmdx/rspec/result_matchers/be_state_matchers.rb +59 -0
  84. data/lib/cmdx/rspec/result_matchers/be_status_matchers.rb +57 -0
  85. data/lib/cmdx/rspec/result_matchers/be_successful_task.rb +87 -0
  86. data/lib/cmdx/rspec/result_matchers/have_bad_outcome.rb +51 -0
  87. data/lib/cmdx/rspec/result_matchers/have_caused_failure.rb +58 -0
  88. data/lib/cmdx/rspec/result_matchers/have_chain_index.rb +59 -0
  89. data/lib/cmdx/rspec/result_matchers/have_context.rb +86 -0
  90. data/lib/cmdx/rspec/result_matchers/have_empty_metadata.rb +54 -0
  91. data/lib/cmdx/rspec/result_matchers/have_good_outcome.rb +52 -0
  92. data/lib/cmdx/rspec/result_matchers/have_metadata.rb +114 -0
  93. data/lib/cmdx/rspec/result_matchers/have_preserved_context.rb +66 -0
  94. data/lib/cmdx/rspec/result_matchers/have_received_thrown_failure.rb +64 -0
  95. data/lib/cmdx/rspec/result_matchers/have_runtime.rb +78 -0
  96. data/lib/cmdx/rspec/result_matchers/have_thrown_failure.rb +76 -0
  97. data/lib/cmdx/rspec/task_matchers/be_well_formed_task.rb +62 -0
  98. data/lib/cmdx/rspec/task_matchers/have_callback.rb +85 -0
  99. data/lib/cmdx/rspec/task_matchers/have_cmd_setting.rb +68 -0
  100. data/lib/cmdx/rspec/task_matchers/have_executed_callbacks.rb +92 -0
  101. data/lib/cmdx/rspec/task_matchers/have_middleware.rb +46 -0
  102. data/lib/cmdx/rspec/task_matchers/have_parameter.rb +181 -0
  103. data/lib/cmdx/task.rb +213 -425
  104. data/lib/cmdx/task_deprecator.rb +55 -0
  105. data/lib/cmdx/task_processor.rb +245 -0
  106. data/lib/cmdx/task_serializer.rb +22 -70
  107. data/lib/cmdx/utils/ansi_color.rb +13 -89
  108. data/lib/cmdx/utils/log_timestamp.rb +13 -42
  109. data/lib/cmdx/utils/monotonic_runtime.rb +13 -63
  110. data/lib/cmdx/utils/name_affix.rb +21 -71
  111. data/lib/cmdx/validator.rb +48 -0
  112. data/lib/cmdx/validator_registry.rb +86 -0
  113. data/lib/cmdx/validators/exclusion.rb +55 -94
  114. data/lib/cmdx/validators/format.rb +31 -85
  115. data/lib/cmdx/validators/inclusion.rb +65 -110
  116. data/lib/cmdx/validators/length.rb +117 -133
  117. data/lib/cmdx/validators/numeric.rb +123 -130
  118. data/lib/cmdx/validators/presence.rb +38 -79
  119. data/lib/cmdx/version.rb +1 -7
  120. data/lib/cmdx/workflow.rb +46 -339
  121. data/lib/cmdx.rb +1 -1
  122. data/lib/generators/cmdx/install_generator.rb +14 -31
  123. data/lib/generators/cmdx/task_generator.rb +39 -55
  124. data/lib/generators/cmdx/templates/install.rb +24 -6
  125. data/lib/generators/cmdx/workflow_generator.rb +41 -66
  126. data/lib/locales/ar.yml +0 -1
  127. data/lib/locales/cs.yml +0 -1
  128. data/lib/locales/da.yml +0 -1
  129. data/lib/locales/de.yml +0 -1
  130. data/lib/locales/el.yml +0 -1
  131. data/lib/locales/en.yml +0 -1
  132. data/lib/locales/es.yml +0 -1
  133. data/lib/locales/fi.yml +0 -1
  134. data/lib/locales/fr.yml +0 -1
  135. data/lib/locales/he.yml +0 -1
  136. data/lib/locales/hi.yml +0 -1
  137. data/lib/locales/it.yml +0 -1
  138. data/lib/locales/ja.yml +0 -1
  139. data/lib/locales/ko.yml +0 -1
  140. data/lib/locales/nl.yml +0 -1
  141. data/lib/locales/no.yml +0 -1
  142. data/lib/locales/pl.yml +0 -1
  143. data/lib/locales/pt.yml +0 -1
  144. data/lib/locales/ru.yml +0 -1
  145. data/lib/locales/sv.yml +0 -1
  146. data/lib/locales/th.yml +0 -1
  147. data/lib/locales/tr.yml +0 -1
  148. data/lib/locales/vi.yml +0 -1
  149. data/lib/locales/zh.yml +0 -1
  150. metadata +34 -8
  151. data/lib/cmdx/parameter_validator.rb +0 -81
  152. data/lib/cmdx/parameter_value.rb +0 -244
  153. data/lib/cmdx/parameters_inspector.rb +0 -72
  154. data/lib/cmdx/parameters_serializer.rb +0 -115
  155. data/lib/cmdx/rspec/result_matchers.rb +0 -917
  156. data/lib/cmdx/rspec/task_matchers.rb +0 -570
  157. data/lib/cmdx/validators/custom.rb +0 -102
@@ -1,205 +1,89 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CMDx
4
- ##
5
- # Thread-safe correlation ID management for tracking related operations across request boundaries.
4
+ # Thread-local correlation ID management for tracing and tracking execution context.
6
5
  #
7
- # The Correlator provides a simple, thread-local storage mechanism for managing correlation
8
- # identifiers throughout the execution lifecycle. It enables tracing related operations
9
- # across different tasks, workflows, and service boundaries within the same execution context.
10
- #
11
- # Correlation IDs are automatically used by CMDx runs when available, providing seamless
12
- # request tracking without requiring explicit parameter passing between tasks.
13
- #
14
- # ## Thread Safety
15
- #
16
- # All correlation operations are thread-local, ensuring that different threads maintain
17
- # separate correlation contexts without interference. This is essential for concurrent
18
- # request processing in multi-threaded applications.
19
- #
20
- # ## Integration with CMDx Runs
21
- #
22
- # When a new CMDx::Chain is created, it automatically uses the current thread's correlation
23
- # ID as its chain identifier if available, falling back to UUID generation if none exists.
24
- #
25
- # @example Basic correlation usage
26
- # CMDx::Correlator.id = "req-12345"
27
- # CMDx::Correlator.id # => "req-12345"
28
- #
29
- # # Chain automatically inherits correlation ID
30
- # result = ProcessOrderTask.call(order_id: 123)
31
- # result.chain.id # => "req-12345"
32
- #
33
- # @example Block-based correlation context
34
- # CMDx::Correlator.use("workflow-operation-456") do
35
- # # All tasks within this block share the same correlation
36
- # ProcessOrderTask.call(order_id: 123)
37
- # SendEmailTask.call(user_id: 456)
38
- # end
39
- # # Correlation context is automatically restored
40
- #
41
- # @example Nested correlation contexts
42
- # CMDx::Correlator.use("parent-operation") do
43
- # CMDx::Correlator.use("child-operation") do
44
- # ProcessOrderTask.call(order_id: 123)
45
- # # Uses "child-operation" as correlation ID
46
- # end
47
- # # Restored to "parent-operation"
48
- # SendEmailTask.call(user_id: 456)
49
- # end
50
- #
51
- # @example Manual correlation management
52
- # # Set correlation ID for current thread
53
- # CMDx::Correlator.id = "manual-correlation"
54
- #
55
- # # Check current correlation
56
- # current_id = CMDx::Correlator.id
57
- #
58
- # # Clear correlation when done
59
- # CMDx::Correlator.clear
60
- #
61
- # @example Middleware integration pattern
62
- # class CorrelationMiddleware
63
- # def call(env)
64
- # correlation_id = env['HTTP_X_CORRELATION_ID'] || CMDx::Correlator.generate
65
- #
66
- # CMDx::Correlator.use(correlation_id) do
67
- # @app.call(env)
68
- # end
69
- # end
70
- # end
71
- #
72
- # @see CMDx::Chain Chain execution context that inherits correlation IDs
73
- # @since 1.0.0
6
+ # This module provides utilities for managing correlation IDs within thread-local storage,
7
+ # enabling request tracing and execution context tracking across task chains and workflows.
8
+ # Each thread maintains its own correlation ID that can be used to correlate related operations.
74
9
  module Correlator
75
10
 
76
- ##
77
- # Thread-local storage key for correlation identifiers.
78
- #
79
- # Uses a Symbol key to avoid potential conflicts with other thread-local
80
- # variables and to ensure consistent access across the correlator methods.
81
- #
82
- # @return [Symbol] the thread-local storage key
83
11
  THREAD_KEY = :cmdx_correlation_id
84
12
 
85
13
  module_function
86
14
 
87
- ##
88
- # Generates a new UUID suitable for use as a correlation identifier.
89
- #
90
- # Creates a RFC 4122 compliant UUID using SecureRandom, providing a globally
91
- # unique identifier suitable for distributed request tracing.
15
+ # Generates a new unique correlation ID using SecureRandom.
16
+ # Prefers UUID v7 when available, falls back to UUID v4.
92
17
  #
93
- # @return [String] a new UUID string in standard format (e.g., "123e4567-e89b-12d3-a456-426614174000")
18
+ # @return [String] a new UUID string for use as correlation ID
94
19
  #
95
- # @example Generating correlation IDs
96
- # id1 = CMDx::Correlator.generate # => "018c2b95-b764-7615-a924-cc5b910ed1e5"
97
- # id2 = CMDx::Correlator.generate # => "018c2b95-b765-7123-b456-dd7c920fe3a8"
98
- # id1 != id2 # => true
20
+ # @example Generate a new correlation ID
21
+ # CMDx::Correlator.generate #=> "f47ac10b-58cc-4372-a567-0e02b2c3d479"
99
22
  def generate
23
+ return SecureRandom.uuid_v7 if SecureRandom.respond_to?(:uuid_v7)
24
+
100
25
  SecureRandom.uuid
101
26
  end
102
27
 
103
- ##
104
- # Retrieves the current thread's correlation identifier.
105
- #
106
- # Returns the correlation ID that was previously set for the current thread,
107
- # or nil if no correlation ID has been established. This method is thread-safe
108
- # and will not interfere with correlation IDs set in other threads.
28
+ # Retrieves the current thread's correlation ID.
109
29
  #
110
- # @return [String, nil] the current correlation ID or nil if none is set
30
+ # @return [String, nil] the current correlation ID or nil if not set
111
31
  #
112
- # @example Checking current correlation
113
- # CMDx::Correlator.id # => nil (when none is set)
32
+ # @example Get current correlation ID
33
+ # CMDx::Correlator.id #=> "f47ac10b-58cc-4372-a567-0e02b2c3d479"
114
34
  #
115
- # CMDx::Correlator.id = "test-correlation"
116
- # CMDx::Correlator.id # => "test-correlation"
35
+ # @example When no correlation ID is set
36
+ # CMDx::Correlator.id #=> nil
117
37
  def id
118
38
  Thread.current[THREAD_KEY]
119
39
  end
120
40
 
121
- ##
122
- # Sets the correlation identifier for the current thread.
123
- #
124
- # Assigns a correlation ID to the current thread's local storage, making it
125
- # available for subsequent operations within the same thread context. The
126
- # correlation ID will persist until explicitly changed or cleared.
41
+ # Sets the current thread's correlation ID.
127
42
  #
128
- # @param value [String, #to_s] the correlation identifier to set
129
- # @return [String] the assigned correlation identifier
43
+ # @param value [String, Symbol] the correlation ID to set
130
44
  #
131
- # @example Setting correlation ID
132
- # CMDx::Correlator.id = "user-request-123"
133
- # CMDx::Correlator.id # => "user-request-123"
45
+ # @return [String, Symbol] the value that was set
134
46
  #
135
- # @example Type coercion
136
- # CMDx::Correlator.id = 12345
137
- # CMDx::Correlator.id # => 12345 (stored as provided)
47
+ # @example Set correlation ID
48
+ # CMDx::Correlator.id = "custom-trace-123"
49
+ # CMDx::Correlator.id #=> "custom-trace-123"
138
50
  def id=(value)
139
51
  Thread.current[THREAD_KEY] = value
140
52
  end
141
53
 
142
- ##
143
- # Clears the correlation identifier for the current thread.
144
- #
145
- # Removes the correlation ID from the current thread's local storage,
146
- # effectively resetting the correlation context. Subsequent calls to
147
- # {#id} will return nil until a new correlation ID is set.
54
+ # Clears the current thread's correlation ID.
148
55
  #
149
56
  # @return [nil] always returns nil
150
57
  #
151
- # @example Clearing correlation
152
- # CMDx::Correlator.id = "temporary-correlation"
153
- # CMDx::Correlator.id # => "temporary-correlation"
154
- #
58
+ # @example Clear correlation ID
155
59
  # CMDx::Correlator.clear
156
- # CMDx::Correlator.id # => nil
60
+ # CMDx::Correlator.id #=> nil
157
61
  def clear
158
62
  Thread.current[THREAD_KEY] = nil
159
63
  end
160
64
 
161
- ##
162
- # Temporarily sets a correlation identifier for the duration of a block.
65
+ # Temporarily uses a correlation ID for the duration of a block.
66
+ # Restores the previous correlation ID after the block completes, even if an exception occurs.
163
67
  #
164
- # Establishes a correlation context for the given block, automatically
165
- # restoring the previous correlation ID when the block completes. This
166
- # method is exception-safe and will restore the original context even
167
- # if the block raises an error.
68
+ # @param value [String, Symbol] the correlation ID to use during block execution
168
69
  #
169
- # This is the preferred method for managing correlation contexts as it
170
- # ensures proper cleanup and supports nested correlation scopes.
70
+ # @return [Object] the result of the block execution
171
71
  #
172
- # @param value [String, #to_s] the correlation identifier to use during block execution
173
- # @yieldreturn [Object] the return value of the block
174
- # @return [Object] the return value of the executed block
72
+ # @raise [TypeError] if value is not a String or Symbol
175
73
  #
176
- # @example Basic usage
177
- # result = CMDx::Correlator.use("operation-123") do
178
- # ProcessOrderTask.call(order_id: 456)
74
+ # @example Use temporary correlation ID
75
+ # CMDx::Correlator.use("temp-123") do
76
+ # puts CMDx::Correlator.id # => "temp-123"
77
+ # # ... perform work ...
179
78
  # end
180
- # # Correlation context is automatically restored
181
- #
182
- # @example Nested contexts
183
- # CMDx::Correlator.use("parent") do
184
- # CMDx::Correlator.id # => "parent"
185
- #
186
- # CMDx::Correlator.use("child") do
187
- # CMDx::Correlator.id # => "child"
188
- # end
79
+ # # Previous correlation ID is restored
189
80
  #
190
- # CMDx::Correlator.id # => "parent" (restored)
191
- # end
192
- #
193
- # @example Exception safety
81
+ # @example With exception handling
194
82
  # CMDx::Correlator.id = "original"
195
- #
196
- # begin
197
- # CMDx::Correlator.use("temporary") do
198
- # raise StandardError, "something went wrong"
199
- # end
200
- # rescue StandardError
201
- # CMDx::Correlator.id # => "original" (still restored)
83
+ # CMDx::Correlator.use("temp") do
84
+ # raise StandardError, "oops"
202
85
  # end
86
+ # # CMDx::Correlator.id is still "original"
203
87
  def use(value)
204
88
  unless value.is_a?(String) || value.is_a?(Symbol)
205
89
  raise TypeError,
data/lib/cmdx/error.rb CHANGED
@@ -2,224 +2,59 @@
2
2
 
3
3
  module CMDx
4
4
 
5
- ##
6
- # Base exception class for all CMDx-specific errors.
7
- # All other CMDx exceptions inherit from this class, providing a common
8
- # hierarchy for error handling and rescue operations.
5
+ # Base exception class for all CMDx-related errors.
9
6
  #
10
- # This allows for catching all CMDx-related exceptions with a single rescue clause
11
- # while still maintaining specific error types for detailed error handling.
12
- #
13
- # @example Catching all CMDx errors
14
- # begin
15
- # ProcessOrderTask.call(invalid_params)
16
- # rescue CMDx::Error => e
17
- # logger.error "CMDx error occurred: #{e.message}"
18
- # end
19
- #
20
- # @example Specific error handling
21
- # begin
22
- # ProcessOrderTask.call(order_id: "invalid")
23
- # rescue CMDx::CoercionError => e
24
- # # Handle type coercion failures
25
- # rescue CMDx::ValidationError => e
26
- # # Handle validation failures
27
- # rescue CMDx::Error => e
28
- # # Handle any other CMDx errors
29
- # end
30
- #
31
- # @see StandardError Ruby's standard error base class
32
- # @since 1.0.0
7
+ # This serves as the root exception class for all errors raised by the CMDx
8
+ # framework. It inherits from StandardError and provides a common base for
9
+ # handling CMDx-specific exceptions.
33
10
  Error = Class.new(StandardError)
34
11
 
35
- ##
36
- # Raised when a value cannot be coerced to the specified type.
37
- # This exception occurs during parameter processing when type coercion fails,
38
- # typically due to incompatible data formats or invalid input values.
39
- #
40
- # CoercionError is raised by the various coercion modules when they encounter
41
- # values that cannot be converted to the target type. Each coercion module
42
- # provides specific error messages indicating the expected type and the
43
- # problematic value.
44
- #
45
- # @example Integer coercion failure
46
- # class MyTask < CMDx::Task
47
- # required :count, type: :integer
48
- # end
49
- #
50
- # # This will raise CoercionError during parameter processing
51
- # MyTask.call(count: "not_a_number")
52
- # # => CMDx::CoercionError: could not coerce into an integer
53
- #
54
- # @example Date coercion failure
55
- # class ScheduleTask < CMDx::Task
56
- # required :due_date, type: :date
57
- # end
58
- #
59
- # ScheduleTask.call(due_date: "invalid_date")
60
- # # => CMDx::CoercionError: could not coerce into a date
12
+ # Raised when parameter coercion fails during task execution.
61
13
  #
62
- # @example Handling coercion errors
63
- # begin
64
- # MyTask.call(count: "invalid")
65
- # rescue CMDx::CoercionError => e
66
- # # Log the coercion failure and provide user-friendly message
67
- # logger.warn "Invalid input format: #{e.message}"
68
- # render json: { error: "Please provide a valid number" }
69
- # end
70
- #
71
- # @see Parameter Parameter type definitions and coercion
72
- # @see ParameterValue Parameter value processing and coercion
73
- # @since 1.0.0
14
+ # This error occurs when a parameter value cannot be converted to the expected
15
+ # type using the registered coercion handlers. It indicates that the provided
16
+ # value is incompatible with the parameter's defined type.
74
17
  CoercionError = Class.new(Error)
75
18
 
76
- ##
77
- # Raised when a task class doesn't implement the required `call` method.
78
- # This exception enforces the CMDx contract that all task classes must
79
- # provide a `call` method containing their business logic.
80
- #
81
- # This error typically occurs during development when creating new task
82
- # classes that inherit from CMDx::Task but forget to implement the
83
- # abstract `call` method.
84
- #
85
- # @example Missing call method
86
- # class IncompleteTask < CMDx::Task
87
- # required :data, type: :string
88
- # # Missing call method implementation
89
- # end
90
- #
91
- # IncompleteTask.call(data: "test")
92
- # # => CMDx::UndefinedCallError: call method not defined in IncompleteTask
19
+ # Raised when a deprecated task is used.
93
20
  #
94
- # @example Proper task implementation
95
- # class CompleteTask < CMDx::Task
96
- # required :data, type: :string
97
- #
98
- # def call
99
- # # Business logic implementation
100
- # context.result = process(data)
101
- # end
102
- # end
103
- #
104
- # @example Handling undefined call errors
105
- # begin
106
- # SomeTask.call(params)
107
- # rescue CMDx::UndefinedCallError => e
108
- # # This should typically only happen during development
109
- # logger.error "Task implementation incomplete: #{e.message}"
110
- # raise # Re-raise as this is a programming error
111
- # end
21
+ # This error occurs when a deprecated task is called. It indicates that the
22
+ # task is no longer supported and should be replaced with a newer alternative.
23
+ DeprecationError = Class.new(Error)
24
+
25
+ # Raised when an abstract method is called without being implemented.
112
26
  #
113
- # @see Task Task base class and call method requirement
114
- # @see Workflow Workflow base class and call method requirement
115
- # @since 1.0.0
27
+ # This error occurs when a subclass fails to implement required abstract methods
28
+ # such as call methods in validators, callbacks, or middleware. It indicates
29
+ # incomplete implementation of required functionality.
116
30
  UndefinedCallError = Class.new(Error)
117
31
 
118
- ##
119
- # Raised when an unknown or unsupported coercion type is specified.
120
- # This exception occurs when parameter definitions reference type coercions
121
- # that don't exist or aren't registered in the CMDx coercion system.
122
- #
123
- # This error helps catch typos in type specifications and ensures that
124
- # only supported data types are used in parameter definitions.
32
+ # Raised when attempting to use an unregistered callback.
125
33
  #
126
- # @example Unknown type specification
127
- # class MyTask < CMDx::Task
128
- # required :value, type: :unknown_type # Typo or unsupported type
129
- # end
130
- #
131
- # MyTask.call(value: "test")
132
- # # => CMDx::UnknownCoercionError: unknown coercion unknown_type
133
- #
134
- # @example Common typos
135
- # class TaskWithTypo < CMDx::Task
136
- # required :count, type: :integr # Should be :integer
137
- # required :flag, type: :bool # Should be :boolean
138
- # required :data, type: :json # Should be :hash
139
- # end
140
- #
141
- # @example Supported types
142
- # class ProperTask < CMDx::Task
143
- # required :id, type: :integer
144
- # required :active, type: :boolean
145
- # required :metadata, type: :hash
146
- # required :tags, type: :array
147
- # required :name, type: :string
148
- # required :score, type: :float
149
- # required :created_at, type: :date_time
150
- # end
151
- #
152
- # @example Handling unknown coercion errors
153
- # begin
154
- # MyTask.call(params)
155
- # rescue CMDx::UnknownCoercionError => e
156
- # # This indicates a programming error in parameter definition
157
- # logger.error "Invalid type specification: #{e.message}"
158
- # raise # Re-raise as this should be fixed in code
159
- # end
34
+ # This error occurs when trying to reference a callback that hasn't been
35
+ # registered in the callback registry. It indicates that the callback name
36
+ # is not recognized or was misspelled.
37
+ UnknownCallbackError = Class.new(Error)
38
+
39
+ # Raised when attempting to use an unregistered coercion type.
160
40
  #
161
- # @see Parameter Parameter type definitions
162
- # @see ParameterValue Type coercion processing
163
- # @since 1.0.0
41
+ # This error occurs when trying to use a parameter type that doesn't have
42
+ # a corresponding coercion handler registered. It indicates that the specified
43
+ # type is not supported by the coercion system.
164
44
  UnknownCoercionError = Class.new(Error)
165
45
 
166
- ##
167
- # Raised when a parameter value fails validation rules.
168
- # This exception occurs during parameter processing when values don't meet
169
- # the specified validation criteria, such as format requirements, length
170
- # constraints, or custom validation logic.
171
- #
172
- # ValidationError provides detailed feedback about why validation failed,
173
- # helping developers and users understand what corrections are needed.
174
- #
175
- # @example Presence validation failure
176
- # class CreateUserTask < CMDx::Task
177
- # required :email, type: :string, presence: true
178
- # end
179
- #
180
- # CreateUserTask.call(email: "")
181
- # # => CMDx::ValidationError: cannot be empty
46
+ # Raised when attempting to use an unregistered validator.
182
47
  #
183
- # @example Format validation failure
184
- # class ValidateEmailTask < CMDx::Task
185
- # required :email, type: :string, format: { with: /@/ }
186
- # end
187
- #
188
- # ValidateEmailTask.call(email: "invalid-email")
189
- # # => CMDx::ValidationError: is an invalid format
190
- #
191
- # @example Length validation failure
192
- # class SetPasswordTask < CMDx::Task
193
- # required :password, type: :string, length: { min: 8 }
194
- # end
195
- #
196
- # SetPasswordTask.call(password: "short")
197
- # # => CMDx::ValidationError: length must be at least 8
198
- #
199
- # @example Custom validation failure
200
- # class ProcessOrderTask < CMDx::Task
201
- # required :quantity, type: :integer, custom: -> (val) { val > 0 }
202
- # end
203
- #
204
- # ProcessOrderTask.call(quantity: -1)
205
- # # => CMDx::ValidationError: is not valid
206
- #
207
- # @example Handling validation errors
208
- # begin
209
- # CreateUserTask.call(email: "", password: "short")
210
- # rescue CMDx::ValidationError => e
211
- # # Provide user-friendly feedback
212
- # render json: {
213
- # error: "Validation failed",
214
- # message: e.message,
215
- # field: extract_field_from_context(e)
216
- # }
217
- # end
48
+ # This error occurs when trying to reference a validator that hasn't been
49
+ # registered in the validator registry. It indicates that the validator name
50
+ # is not recognized or was misspelled.
51
+ UnknownValidatorError = Class.new(Error)
52
+
53
+ # Raised when parameter validation fails during task execution.
218
54
  #
219
- # @see Parameter Parameter validation options
220
- # @see ParameterValue Validation processing
221
- # @see Validators Validation modules (Presence, Format, Length, etc.)
222
- # @since 1.0.0
55
+ # This error occurs when a parameter value doesn't meet the validation criteria
56
+ # defined by the validator. It indicates that the provided value violates
57
+ # business rules or data integrity constraints.
223
58
  ValidationError = Class.new(Error)
224
59
 
225
60
  end