cmdx 1.0.1 → 1.1.1

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 (170) hide show
  1. checksums.yaml +4 -4
  2. data/.cursor/prompts/docs.md +9 -0
  3. data/.cursor/prompts/rspec.md +21 -0
  4. data/.cursor/prompts/yardoc.md +13 -0
  5. data/.rubocop.yml +2 -0
  6. data/CHANGELOG.md +29 -3
  7. data/README.md +2 -1
  8. data/docs/ai_prompts.md +269 -195
  9. data/docs/basics/call.md +126 -60
  10. data/docs/basics/chain.md +190 -160
  11. data/docs/basics/context.md +242 -154
  12. data/docs/basics/setup.md +302 -32
  13. data/docs/callbacks.md +382 -119
  14. data/docs/configuration.md +211 -49
  15. data/docs/deprecation.md +245 -0
  16. data/docs/getting_started.md +161 -39
  17. data/docs/internationalization.md +590 -70
  18. data/docs/interruptions/exceptions.md +135 -118
  19. data/docs/interruptions/faults.md +152 -127
  20. data/docs/interruptions/halt.md +134 -80
  21. data/docs/logging.md +183 -120
  22. data/docs/middlewares.md +165 -392
  23. data/docs/outcomes/result.md +140 -112
  24. data/docs/outcomes/states.md +134 -99
  25. data/docs/outcomes/statuses.md +204 -146
  26. data/docs/parameters/coercions.md +251 -289
  27. data/docs/parameters/defaults.md +224 -169
  28. data/docs/parameters/definitions.md +289 -141
  29. data/docs/parameters/namespacing.md +250 -161
  30. data/docs/parameters/validations.md +247 -159
  31. data/docs/testing.md +196 -203
  32. data/docs/workflows.md +146 -101
  33. data/lib/cmdx/.DS_Store +0 -0
  34. data/lib/cmdx/callback.rb +39 -55
  35. data/lib/cmdx/callback_registry.rb +80 -73
  36. data/lib/cmdx/chain.rb +65 -122
  37. data/lib/cmdx/chain_inspector.rb +23 -116
  38. data/lib/cmdx/chain_serializer.rb +34 -146
  39. data/lib/cmdx/coercion.rb +57 -0
  40. data/lib/cmdx/coercion_registry.rb +113 -0
  41. data/lib/cmdx/coercions/array.rb +18 -36
  42. data/lib/cmdx/coercions/big_decimal.rb +21 -33
  43. data/lib/cmdx/coercions/boolean.rb +21 -40
  44. data/lib/cmdx/coercions/complex.rb +18 -31
  45. data/lib/cmdx/coercions/date.rb +20 -39
  46. data/lib/cmdx/coercions/date_time.rb +22 -39
  47. data/lib/cmdx/coercions/float.rb +19 -32
  48. data/lib/cmdx/coercions/hash.rb +22 -41
  49. data/lib/cmdx/coercions/integer.rb +20 -33
  50. data/lib/cmdx/coercions/rational.rb +20 -32
  51. data/lib/cmdx/coercions/string.rb +23 -31
  52. data/lib/cmdx/coercions/time.rb +24 -40
  53. data/lib/cmdx/coercions/virtual.rb +14 -31
  54. data/lib/cmdx/configuration.rb +101 -162
  55. data/lib/cmdx/context.rb +34 -166
  56. data/lib/cmdx/core_ext/hash.rb +42 -67
  57. data/lib/cmdx/core_ext/module.rb +35 -79
  58. data/lib/cmdx/core_ext/object.rb +63 -98
  59. data/lib/cmdx/correlator.rb +59 -154
  60. data/lib/cmdx/error.rb +37 -202
  61. data/lib/cmdx/errors.rb +153 -216
  62. data/lib/cmdx/fault.rb +68 -150
  63. data/lib/cmdx/faults.rb +26 -137
  64. data/lib/cmdx/immutator.rb +22 -110
  65. data/lib/cmdx/lazy_struct.rb +110 -186
  66. data/lib/cmdx/log_formatters/json.rb +14 -40
  67. data/lib/cmdx/log_formatters/key_value.rb +14 -40
  68. data/lib/cmdx/log_formatters/line.rb +14 -48
  69. data/lib/cmdx/log_formatters/logstash.rb +14 -57
  70. data/lib/cmdx/log_formatters/pretty_json.rb +14 -50
  71. data/lib/cmdx/log_formatters/pretty_key_value.rb +13 -46
  72. data/lib/cmdx/log_formatters/pretty_line.rb +16 -54
  73. data/lib/cmdx/log_formatters/raw.rb +19 -49
  74. data/lib/cmdx/logger.rb +22 -79
  75. data/lib/cmdx/logger_ansi.rb +31 -72
  76. data/lib/cmdx/logger_serializer.rb +74 -103
  77. data/lib/cmdx/middleware.rb +56 -60
  78. data/lib/cmdx/middleware_registry.rb +82 -77
  79. data/lib/cmdx/middlewares/correlate.rb +41 -226
  80. data/lib/cmdx/middlewares/timeout.rb +46 -185
  81. data/lib/cmdx/parameter.rb +167 -183
  82. data/lib/cmdx/parameter_evaluator.rb +231 -0
  83. data/lib/cmdx/parameter_inspector.rb +37 -55
  84. data/lib/cmdx/parameter_registry.rb +65 -84
  85. data/lib/cmdx/parameter_serializer.rb +32 -76
  86. data/lib/cmdx/railtie.rb +24 -107
  87. data/lib/cmdx/result.rb +254 -259
  88. data/lib/cmdx/result_ansi.rb +28 -80
  89. data/lib/cmdx/result_inspector.rb +34 -70
  90. data/lib/cmdx/result_logger.rb +23 -77
  91. data/lib/cmdx/result_serializer.rb +59 -125
  92. data/lib/cmdx/rspec/matchers.rb +28 -0
  93. data/lib/cmdx/rspec/result_matchers/be_executed.rb +42 -0
  94. data/lib/cmdx/rspec/result_matchers/be_failed_task.rb +94 -0
  95. data/lib/cmdx/rspec/result_matchers/be_skipped_task.rb +94 -0
  96. data/lib/cmdx/rspec/result_matchers/be_state_matchers.rb +59 -0
  97. data/lib/cmdx/rspec/result_matchers/be_status_matchers.rb +57 -0
  98. data/lib/cmdx/rspec/result_matchers/be_successful_task.rb +87 -0
  99. data/lib/cmdx/rspec/result_matchers/have_bad_outcome.rb +51 -0
  100. data/lib/cmdx/rspec/result_matchers/have_caused_failure.rb +58 -0
  101. data/lib/cmdx/rspec/result_matchers/have_chain_index.rb +59 -0
  102. data/lib/cmdx/rspec/result_matchers/have_context.rb +86 -0
  103. data/lib/cmdx/rspec/result_matchers/have_empty_metadata.rb +54 -0
  104. data/lib/cmdx/rspec/result_matchers/have_good_outcome.rb +52 -0
  105. data/lib/cmdx/rspec/result_matchers/have_metadata.rb +114 -0
  106. data/lib/cmdx/rspec/result_matchers/have_preserved_context.rb +66 -0
  107. data/lib/cmdx/rspec/result_matchers/have_received_thrown_failure.rb +64 -0
  108. data/lib/cmdx/rspec/result_matchers/have_runtime.rb +78 -0
  109. data/lib/cmdx/rspec/result_matchers/have_thrown_failure.rb +76 -0
  110. data/lib/cmdx/rspec/task_matchers/be_well_formed_task.rb +62 -0
  111. data/lib/cmdx/rspec/task_matchers/have_callback.rb +85 -0
  112. data/lib/cmdx/rspec/task_matchers/have_cmd_setting.rb +68 -0
  113. data/lib/cmdx/rspec/task_matchers/have_executed_callbacks.rb +92 -0
  114. data/lib/cmdx/rspec/task_matchers/have_middleware.rb +46 -0
  115. data/lib/cmdx/rspec/task_matchers/have_parameter.rb +181 -0
  116. data/lib/cmdx/task.rb +336 -427
  117. data/lib/cmdx/task_deprecator.rb +52 -0
  118. data/lib/cmdx/task_processor.rb +246 -0
  119. data/lib/cmdx/task_serializer.rb +34 -69
  120. data/lib/cmdx/utils/ansi_color.rb +13 -89
  121. data/lib/cmdx/utils/log_timestamp.rb +13 -42
  122. data/lib/cmdx/utils/monotonic_runtime.rb +11 -63
  123. data/lib/cmdx/utils/name_affix.rb +21 -71
  124. data/lib/cmdx/validator.rb +57 -0
  125. data/lib/cmdx/validator_registry.rb +108 -0
  126. data/lib/cmdx/validators/exclusion.rb +55 -94
  127. data/lib/cmdx/validators/format.rb +31 -85
  128. data/lib/cmdx/validators/inclusion.rb +65 -110
  129. data/lib/cmdx/validators/length.rb +117 -133
  130. data/lib/cmdx/validators/numeric.rb +123 -130
  131. data/lib/cmdx/validators/presence.rb +38 -79
  132. data/lib/cmdx/version.rb +1 -7
  133. data/lib/cmdx/workflow.rb +58 -330
  134. data/lib/cmdx.rb +1 -1
  135. data/lib/generators/cmdx/install_generator.rb +14 -31
  136. data/lib/generators/cmdx/task_generator.rb +39 -55
  137. data/lib/generators/cmdx/templates/install.rb +24 -6
  138. data/lib/generators/cmdx/workflow_generator.rb +41 -66
  139. data/lib/locales/ar.yml +0 -1
  140. data/lib/locales/cs.yml +0 -1
  141. data/lib/locales/da.yml +0 -1
  142. data/lib/locales/de.yml +0 -1
  143. data/lib/locales/el.yml +0 -1
  144. data/lib/locales/en.yml +0 -1
  145. data/lib/locales/es.yml +0 -1
  146. data/lib/locales/fi.yml +0 -1
  147. data/lib/locales/fr.yml +0 -1
  148. data/lib/locales/he.yml +0 -1
  149. data/lib/locales/hi.yml +0 -1
  150. data/lib/locales/it.yml +0 -1
  151. data/lib/locales/ja.yml +0 -1
  152. data/lib/locales/ko.yml +0 -1
  153. data/lib/locales/nl.yml +0 -1
  154. data/lib/locales/no.yml +0 -1
  155. data/lib/locales/pl.yml +0 -1
  156. data/lib/locales/pt.yml +0 -1
  157. data/lib/locales/ru.yml +0 -1
  158. data/lib/locales/sv.yml +0 -1
  159. data/lib/locales/th.yml +0 -1
  160. data/lib/locales/tr.yml +0 -1
  161. data/lib/locales/vi.yml +0 -1
  162. data/lib/locales/zh.yml +0 -1
  163. metadata +36 -8
  164. data/lib/cmdx/parameter_validator.rb +0 -81
  165. data/lib/cmdx/parameter_value.rb +0 -244
  166. data/lib/cmdx/parameters_inspector.rb +0 -72
  167. data/lib/cmdx/parameters_serializer.rb +0 -115
  168. data/lib/cmdx/rspec/result_matchers.rb +0 -917
  169. data/lib/cmdx/rspec/task_matchers.rb +0 -570
  170. data/lib/cmdx/validators/custom.rb +0 -102
@@ -1,205 +1,110 @@
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-safe correlation ID management for distributed tracing and request tracking.
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
+ # Correlator provides functionality to generate, store, and manage correlation IDs
7
+ # across thread boundaries for request tracing, logging correlation, and distributed
8
+ # system monitoring. Correlation IDs are stored in thread-local storage to ensure
9
+ # thread safety and isolation between concurrent operations.
74
10
  module Correlator
75
11
 
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
12
  THREAD_KEY = :cmdx_correlation_id
84
13
 
85
14
  module_function
86
15
 
87
- ##
88
- # Generates a new UUID suitable for use as a correlation identifier.
16
+ # Generates a new correlation ID using the best available UUID algorithm.
89
17
  #
90
- # Creates a RFC 4122 compliant UUID using SecureRandom, providing a globally
91
- # unique identifier suitable for distributed request tracing.
18
+ # Attempts to use UUID v7 (time-ordered) if available in Ruby 3.3+, otherwise
19
+ # falls back to standard UUID v4. UUID v7 provides better database indexing
20
+ # performance and natural time-based ordering for correlation tracking.
92
21
  #
93
- # @return [String] a new UUID string in standard format (e.g., "123e4567-e89b-12d3-a456-426614174000")
22
+ # @return [String] a new UUID correlation ID
94
23
  #
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
24
+ # @example Generate a correlation ID
25
+ # Correlator.generate #=> "01234567-89ab-7def-0123-456789abcdef"
26
+ #
27
+ # @example Using the generated ID for logging
28
+ # correlation_id = Correlator.generate
29
+ # logger.info "Request started", correlation_id: correlation_id
99
30
  def generate
31
+ return SecureRandom.uuid_v7 if SecureRandom.respond_to?(:uuid_v7)
32
+
100
33
  SecureRandom.uuid
101
34
  end
102
35
 
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.
36
+ # Retrieves the current correlation ID for the active thread.
109
37
  #
110
- # @return [String, nil] the current correlation ID or nil if none is set
38
+ # Returns the correlation ID that has been set for the current thread's
39
+ # execution context. Returns nil if no correlation ID has been established
40
+ # for the current thread.
111
41
  #
112
- # @example Checking current correlation
113
- # CMDx::Correlator.id # => nil (when none is set)
42
+ # @return [String, nil] the current thread's correlation ID, or nil if not set
114
43
  #
115
- # CMDx::Correlator.id = "test-correlation"
116
- # CMDx::Correlator.id # => "test-correlation"
44
+ # @example Get current correlation ID
45
+ # Correlator.id #=> "01234567-89ab-7def-0123-456789abcdef"
117
46
  def id
118
47
  Thread.current[THREAD_KEY]
119
48
  end
120
49
 
121
- ##
122
- # Sets the correlation identifier for the current thread.
50
+ # Sets the correlation ID for the current thread.
123
51
  #
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.
52
+ # Establishes a correlation ID in thread-local storage that will be
53
+ # accessible to all operations within the current thread's execution
54
+ # context. This ID will persist until explicitly changed or cleared.
127
55
  #
128
- # @param value [String, #to_s] the correlation identifier to set
129
- # @return [String] the assigned correlation identifier
56
+ # @param value [String, Symbol] the correlation ID to set for this thread
130
57
  #
131
- # @example Setting correlation ID
132
- # CMDx::Correlator.id = "user-request-123"
133
- # CMDx::Correlator.id # => "user-request-123"
58
+ # @return [String, Symbol] the assigned correlation ID value
134
59
  #
135
- # @example Type coercion
136
- # CMDx::Correlator.id = 12345
137
- # CMDx::Correlator.id # => 12345 (stored as provided)
60
+ # @example Set a custom correlation ID
61
+ # Correlator.id = "custom-trace-123"
62
+ #
63
+ # @example Set a generated correlation ID
64
+ # Correlator.id = Correlator.generate
138
65
  def id=(value)
139
66
  Thread.current[THREAD_KEY] = value
140
67
  end
141
68
 
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.
69
+ # Clears the correlation ID for the current thread.
148
70
  #
149
- # @return [nil] always returns nil
71
+ # Removes the correlation ID from thread-local storage, effectively
72
+ # resetting the correlation context for the current thread. Useful
73
+ # for cleanup between request processing or test scenarios.
150
74
  #
151
- # @example Clearing correlation
152
- # CMDx::Correlator.id = "temporary-correlation"
153
- # CMDx::Correlator.id # => "temporary-correlation"
75
+ # @return [nil] always returns nil after clearing
154
76
  #
155
- # CMDx::Correlator.clear
156
- # CMDx::Correlator.id # => nil
77
+ # @example Clear correlation ID
78
+ # Correlator.clear
79
+ # Correlator.id #=> nil
157
80
  def clear
158
81
  Thread.current[THREAD_KEY] = nil
159
82
  end
160
83
 
161
- ##
162
- # Temporarily sets a correlation identifier for the duration of a block.
84
+ # Temporarily sets a correlation ID for the duration of a block execution.
163
85
  #
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.
86
+ # Establishes a correlation ID context for the provided block, automatically
87
+ # restoring the previous correlation ID when the block completes. This ensures
88
+ # proper correlation ID isolation for nested operations or temporary contexts.
168
89
  #
169
- # This is the preferred method for managing correlation contexts as it
170
- # ensures proper cleanup and supports nested correlation scopes.
90
+ # @param value [String, Symbol] the temporary correlation ID to use during block execution
171
91
  #
172
- # @param value [String, #to_s] the correlation identifier to use during block execution
173
- # @yieldreturn [Object] the return value of the block
174
92
  # @return [Object] the return value of the executed block
175
93
  #
176
- # @example Basic usage
177
- # result = CMDx::Correlator.use("operation-123") do
178
- # ProcessOrderTask.call(order_id: 456)
179
- # 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
94
+ # @raise [TypeError] if the provided value is not a String or Symbol
189
95
  #
190
- # CMDx::Correlator.id # => "parent" (restored)
96
+ # @example Use temporary correlation ID
97
+ # Correlator.use("temp-id-123") do
98
+ # logger.info "Processing with temporary ID"
99
+ # perform_operation
191
100
  # end
192
101
  #
193
- # @example Exception safety
194
- # 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)
102
+ # @example Nested correlation contexts
103
+ # Correlator.id = "parent-id"
104
+ # Correlator.use("child-id") do
105
+ # puts Correlator.id #=> "child-id"
202
106
  # end
107
+ # puts Correlator.id #=> "parent-id"
203
108
  def use(value)
204
109
  unless value.is_a?(String) || value.is_a?(Symbol)
205
110
  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