cmdx 1.1.2 → 1.5.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.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/.cursor/prompts/docs.md +4 -1
- data/.cursor/prompts/llms.md +20 -0
- data/.cursor/prompts/rspec.md +4 -1
- data/.cursor/prompts/yardoc.md +3 -2
- data/.cursor/rules/cursor-instructions.mdc +56 -1
- data/.irbrc +6 -0
- data/.rubocop.yml +29 -18
- data/CHANGELOG.md +5 -133
- data/LLM.md +3317 -0
- data/README.md +68 -44
- data/docs/attributes/coercions.md +162 -0
- data/docs/attributes/defaults.md +90 -0
- data/docs/attributes/definitions.md +281 -0
- data/docs/attributes/naming.md +78 -0
- data/docs/attributes/validations.md +309 -0
- data/docs/basics/chain.md +56 -249
- data/docs/basics/context.md +56 -289
- data/docs/basics/execution.md +114 -0
- data/docs/basics/setup.md +37 -334
- data/docs/callbacks.md +89 -467
- data/docs/deprecation.md +91 -174
- data/docs/getting_started.md +212 -202
- data/docs/internationalization.md +11 -647
- data/docs/interruptions/exceptions.md +23 -198
- data/docs/interruptions/faults.md +71 -151
- data/docs/interruptions/halt.md +109 -186
- data/docs/logging.md +44 -256
- data/docs/middlewares.md +113 -426
- data/docs/outcomes/result.md +81 -228
- data/docs/outcomes/states.md +33 -221
- data/docs/outcomes/statuses.md +21 -311
- data/docs/tips_and_tricks.md +120 -70
- data/docs/workflows.md +99 -283
- data/lib/cmdx/.DS_Store +0 -0
- data/lib/cmdx/attribute.rb +229 -0
- data/lib/cmdx/attribute_registry.rb +94 -0
- data/lib/cmdx/attribute_value.rb +193 -0
- data/lib/cmdx/callback_registry.rb +69 -77
- data/lib/cmdx/chain.rb +56 -73
- data/lib/cmdx/coercion_registry.rb +52 -68
- data/lib/cmdx/coercions/array.rb +19 -18
- data/lib/cmdx/coercions/big_decimal.rb +20 -24
- data/lib/cmdx/coercions/boolean.rb +26 -25
- data/lib/cmdx/coercions/complex.rb +21 -22
- data/lib/cmdx/coercions/date.rb +25 -23
- data/lib/cmdx/coercions/date_time.rb +24 -25
- data/lib/cmdx/coercions/float.rb +25 -22
- data/lib/cmdx/coercions/hash.rb +31 -32
- data/lib/cmdx/coercions/integer.rb +30 -24
- data/lib/cmdx/coercions/rational.rb +29 -24
- data/lib/cmdx/coercions/string.rb +19 -22
- data/lib/cmdx/coercions/symbol.rb +37 -0
- data/lib/cmdx/coercions/time.rb +26 -25
- data/lib/cmdx/configuration.rb +49 -108
- data/lib/cmdx/context.rb +222 -44
- data/lib/cmdx/deprecator.rb +61 -0
- data/lib/cmdx/errors.rb +42 -252
- data/lib/cmdx/exceptions.rb +39 -0
- data/lib/cmdx/faults.rb +78 -39
- data/lib/cmdx/freezer.rb +51 -0
- data/lib/cmdx/identifier.rb +30 -0
- data/lib/cmdx/locale.rb +52 -0
- data/lib/cmdx/log_formatters/json.rb +21 -22
- data/lib/cmdx/log_formatters/key_value.rb +20 -22
- data/lib/cmdx/log_formatters/line.rb +15 -22
- data/lib/cmdx/log_formatters/logstash.rb +22 -23
- data/lib/cmdx/log_formatters/raw.rb +16 -22
- data/lib/cmdx/middleware_registry.rb +70 -74
- data/lib/cmdx/middlewares/correlate.rb +90 -54
- data/lib/cmdx/middlewares/runtime.rb +58 -0
- data/lib/cmdx/middlewares/timeout.rb +48 -68
- data/lib/cmdx/railtie.rb +12 -45
- data/lib/cmdx/result.rb +229 -314
- data/lib/cmdx/task.rb +194 -366
- data/lib/cmdx/utils/call.rb +49 -0
- data/lib/cmdx/utils/condition.rb +71 -0
- data/lib/cmdx/utils/format.rb +61 -0
- data/lib/cmdx/validator_registry.rb +63 -72
- data/lib/cmdx/validators/exclusion.rb +38 -67
- data/lib/cmdx/validators/format.rb +48 -49
- data/lib/cmdx/validators/inclusion.rb +43 -74
- data/lib/cmdx/validators/length.rb +91 -154
- data/lib/cmdx/validators/numeric.rb +87 -162
- data/lib/cmdx/validators/presence.rb +37 -50
- data/lib/cmdx/version.rb +1 -1
- data/lib/cmdx/worker.rb +178 -0
- data/lib/cmdx/workflow.rb +85 -81
- data/lib/cmdx.rb +19 -13
- data/lib/generators/cmdx/install_generator.rb +14 -13
- data/lib/generators/cmdx/task_generator.rb +25 -50
- data/lib/generators/cmdx/templates/install.rb +11 -46
- data/lib/generators/cmdx/templates/task.rb.tt +3 -2
- data/lib/locales/en.yml +18 -4
- data/src/cmdx-logo.png +0 -0
- metadata +32 -116
- data/docs/ai_prompts.md +0 -393
- data/docs/basics/call.md +0 -317
- data/docs/configuration.md +0 -344
- data/docs/parameters/coercions.md +0 -396
- data/docs/parameters/defaults.md +0 -335
- data/docs/parameters/definitions.md +0 -446
- data/docs/parameters/namespacing.md +0 -378
- data/docs/parameters/validations.md +0 -405
- data/docs/testing.md +0 -553
- data/lib/cmdx/callback.rb +0 -53
- data/lib/cmdx/chain_inspector.rb +0 -56
- data/lib/cmdx/chain_serializer.rb +0 -63
- data/lib/cmdx/coercion.rb +0 -57
- data/lib/cmdx/coercions/virtual.rb +0 -29
- data/lib/cmdx/core_ext/hash.rb +0 -83
- data/lib/cmdx/core_ext/module.rb +0 -98
- data/lib/cmdx/core_ext/object.rb +0 -125
- data/lib/cmdx/correlator.rb +0 -122
- data/lib/cmdx/error.rb +0 -67
- data/lib/cmdx/fault.rb +0 -140
- data/lib/cmdx/immutator.rb +0 -52
- data/lib/cmdx/lazy_struct.rb +0 -246
- data/lib/cmdx/log_formatters/pretty_json.rb +0 -40
- data/lib/cmdx/log_formatters/pretty_key_value.rb +0 -38
- data/lib/cmdx/log_formatters/pretty_line.rb +0 -41
- data/lib/cmdx/logger.rb +0 -49
- data/lib/cmdx/logger_ansi.rb +0 -68
- data/lib/cmdx/logger_serializer.rb +0 -116
- data/lib/cmdx/middleware.rb +0 -70
- data/lib/cmdx/parameter.rb +0 -312
- data/lib/cmdx/parameter_evaluator.rb +0 -231
- data/lib/cmdx/parameter_inspector.rb +0 -66
- data/lib/cmdx/parameter_registry.rb +0 -106
- data/lib/cmdx/parameter_serializer.rb +0 -59
- data/lib/cmdx/result_ansi.rb +0 -71
- data/lib/cmdx/result_inspector.rb +0 -71
- data/lib/cmdx/result_logger.rb +0 -59
- data/lib/cmdx/result_serializer.rb +0 -104
- data/lib/cmdx/rspec/matchers.rb +0 -28
- data/lib/cmdx/rspec/result_matchers/be_executed.rb +0 -42
- data/lib/cmdx/rspec/result_matchers/be_failed_task.rb +0 -94
- data/lib/cmdx/rspec/result_matchers/be_skipped_task.rb +0 -94
- data/lib/cmdx/rspec/result_matchers/be_state_matchers.rb +0 -59
- data/lib/cmdx/rspec/result_matchers/be_status_matchers.rb +0 -57
- data/lib/cmdx/rspec/result_matchers/be_successful_task.rb +0 -87
- data/lib/cmdx/rspec/result_matchers/have_bad_outcome.rb +0 -51
- data/lib/cmdx/rspec/result_matchers/have_caused_failure.rb +0 -58
- data/lib/cmdx/rspec/result_matchers/have_chain_index.rb +0 -59
- data/lib/cmdx/rspec/result_matchers/have_context.rb +0 -86
- data/lib/cmdx/rspec/result_matchers/have_empty_metadata.rb +0 -54
- data/lib/cmdx/rspec/result_matchers/have_good_outcome.rb +0 -52
- data/lib/cmdx/rspec/result_matchers/have_metadata.rb +0 -114
- data/lib/cmdx/rspec/result_matchers/have_preserved_context.rb +0 -66
- data/lib/cmdx/rspec/result_matchers/have_received_thrown_failure.rb +0 -64
- data/lib/cmdx/rspec/result_matchers/have_runtime.rb +0 -78
- data/lib/cmdx/rspec/result_matchers/have_thrown_failure.rb +0 -76
- data/lib/cmdx/rspec/task_matchers/be_well_formed_task.rb +0 -62
- data/lib/cmdx/rspec/task_matchers/have_callback.rb +0 -85
- data/lib/cmdx/rspec/task_matchers/have_cmd_setting.rb +0 -68
- data/lib/cmdx/rspec/task_matchers/have_executed_callbacks.rb +0 -92
- data/lib/cmdx/rspec/task_matchers/have_middleware.rb +0 -46
- data/lib/cmdx/rspec/task_matchers/have_parameter.rb +0 -181
- data/lib/cmdx/task_deprecator.rb +0 -58
- data/lib/cmdx/task_processor.rb +0 -246
- data/lib/cmdx/task_serializer.rb +0 -57
- data/lib/cmdx/utils/ansi_color.rb +0 -73
- data/lib/cmdx/utils/log_timestamp.rb +0 -36
- data/lib/cmdx/utils/monotonic_runtime.rb +0 -34
- data/lib/cmdx/utils/name_affix.rb +0 -52
- data/lib/cmdx/validator.rb +0 -57
- data/lib/generators/cmdx/templates/workflow.rb.tt +0 -7
- data/lib/generators/cmdx/workflow_generator.rb +0 -84
- data/lib/locales/ar.yml +0 -35
- data/lib/locales/cs.yml +0 -35
- data/lib/locales/da.yml +0 -35
- data/lib/locales/de.yml +0 -35
- data/lib/locales/el.yml +0 -35
- data/lib/locales/es.yml +0 -35
- data/lib/locales/fi.yml +0 -35
- data/lib/locales/fr.yml +0 -35
- data/lib/locales/he.yml +0 -35
- data/lib/locales/hi.yml +0 -35
- data/lib/locales/it.yml +0 -35
- data/lib/locales/ja.yml +0 -35
- data/lib/locales/ko.yml +0 -35
- data/lib/locales/nl.yml +0 -35
- data/lib/locales/no.yml +0 -35
- data/lib/locales/pl.yml +0 -35
- data/lib/locales/pt.yml +0 -35
- data/lib/locales/ru.yml +0 -35
- data/lib/locales/sv.yml +0 -35
- data/lib/locales/th.yml +0 -35
- data/lib/locales/tr.yml +0 -35
- data/lib/locales/vi.yml +0 -35
- data/lib/locales/zh.yml +0 -35
data/docs/outcomes/result.md
CHANGED
@@ -4,153 +4,98 @@ The result object is the comprehensive return value of task execution, providing
|
|
4
4
|
|
5
5
|
## Table of Contents
|
6
6
|
|
7
|
-
- [
|
8
|
-
- [
|
9
|
-
- [
|
10
|
-
- [
|
11
|
-
- [Runtime and Performance](#runtime-and-performance)
|
12
|
-
- [Failure Chain Analysis](#failure-chain-analysis)
|
7
|
+
- [Result Attributes](#result-attributes)
|
8
|
+
- [Lifecycle Information](#lifecycle-information)
|
9
|
+
- [Outcome Analysis](#outcome-analysis)
|
10
|
+
- [Chain Analysis](#chain-analysis)
|
13
11
|
- [Index and Position](#index-and-position)
|
14
|
-
- [
|
12
|
+
- [Handlers](#handlers)
|
15
13
|
- [Pattern Matching](#pattern-matching)
|
16
|
-
- [
|
14
|
+
- [Array Pattern](#array-pattern)
|
15
|
+
- [Hash Pattern](#hash-pattern)
|
16
|
+
- [Pattern Guards](#pattern-guards)
|
17
17
|
|
18
|
-
##
|
18
|
+
## Result Attributes
|
19
19
|
|
20
|
-
|
21
|
-
# Basic result inspection
|
22
|
-
result = ProcessOrderTask.call(order_id: 123)
|
23
|
-
result.success? # → true/false
|
24
|
-
result.failed? # → true/false
|
25
|
-
result.runtime # → 0.5 (seconds)
|
26
|
-
|
27
|
-
# Fluent callbacks
|
28
|
-
result
|
29
|
-
.on_success { |r| send_notification(r.context) }
|
30
|
-
.on_failed { |r| handle_error(r.metadata) }
|
20
|
+
Every result provides access to essential execution information:
|
31
21
|
|
32
|
-
|
33
|
-
|
34
|
-
original = result.caused_failure # Find root cause
|
35
|
-
thrower = result.threw_failure # Find failure source
|
36
|
-
end
|
37
|
-
```
|
22
|
+
> [!IMPORTANT]
|
23
|
+
> Result objects are immutable after task execution completes and reflect the final state.
|
38
24
|
|
39
|
-
|
25
|
+
```ruby
|
26
|
+
result = BuildApplication.execute(version: "1.2.3")
|
40
27
|
|
41
|
-
|
42
|
-
|
28
|
+
# Object data
|
29
|
+
result.task #=> <BuildApplication>
|
30
|
+
result.context #=> <CMDx::Context>
|
31
|
+
result.chain #=> <CMDx::Chain>
|
43
32
|
|
44
|
-
|
33
|
+
# Execution data
|
34
|
+
result.state #=> "interrupted"
|
35
|
+
result.status #=> "failed"
|
45
36
|
|
46
|
-
|
47
|
-
result
|
48
|
-
|
49
|
-
|
50
|
-
result.task # → ProcessOrderTask instance
|
51
|
-
result.context # → CMDx::Context with all task data
|
52
|
-
result.chain # → CMDx::Chain execution tracking
|
53
|
-
result.metadata # → Hash with execution metadata
|
54
|
-
|
55
|
-
# Execution information
|
56
|
-
result.id # → "abc123..." (unique execution ID)
|
57
|
-
result.state # → "complete"
|
58
|
-
result.status # → "success"
|
59
|
-
result.runtime # → 0.5 (execution time in seconds)
|
37
|
+
# Fault data
|
38
|
+
result.reason #=> "Build tool not found"
|
39
|
+
result.cause #=> <CMDx::FailFault>
|
40
|
+
result.metadata #=> { error_code: "BUILD_TOOL.NOT_FOUND" }
|
60
41
|
```
|
61
42
|
|
62
|
-
##
|
43
|
+
## Lifecycle Information
|
63
44
|
|
64
45
|
Results provide comprehensive methods for checking execution state and status:
|
65
46
|
|
66
47
|
```ruby
|
67
|
-
result =
|
48
|
+
result = BuildApplication.execute(version: "1.2.3")
|
68
49
|
|
69
50
|
# State predicates (execution lifecycle)
|
70
|
-
result.complete?
|
71
|
-
result.interrupted?
|
72
|
-
result.executed?
|
51
|
+
result.complete? #=> true (successful completion)
|
52
|
+
result.interrupted? #=> false (no interruption)
|
53
|
+
result.executed? #=> true (execution finished)
|
73
54
|
|
74
55
|
# Status predicates (execution outcome)
|
75
|
-
result.success?
|
76
|
-
result.failed?
|
77
|
-
result.skipped?
|
56
|
+
result.success? #=> true (successful execution)
|
57
|
+
result.failed? #=> false (no failure)
|
58
|
+
result.skipped? #=> false (not skipped)
|
78
59
|
|
79
60
|
# Outcome categorization
|
80
|
-
result.good?
|
81
|
-
result.bad?
|
61
|
+
result.good? #=> true (success or skipped)
|
62
|
+
result.bad? #=> false (skipped or failed)
|
82
63
|
```
|
83
64
|
|
84
|
-
##
|
65
|
+
## Outcome Analysis
|
85
66
|
|
86
|
-
Results provide unified outcome determination:
|
67
|
+
Results provide unified outcome determination depending on the fault causal chain:
|
87
68
|
|
88
69
|
```ruby
|
89
|
-
result =
|
70
|
+
result = BuildApplication.execute(version: "1.2.3")
|
90
71
|
|
91
|
-
result.outcome
|
72
|
+
result.outcome #=> "success" (state and status)
|
92
73
|
```
|
93
74
|
|
94
|
-
##
|
75
|
+
## Chain Analysis
|
95
76
|
|
96
|
-
|
77
|
+
Use these methods to trace the root cause of faults or trace the cause points.
|
97
78
|
|
98
79
|
```ruby
|
99
|
-
result =
|
100
|
-
|
101
|
-
# Execution timing
|
102
|
-
result.runtime # → 0.5 (total execution time in seconds)
|
103
|
-
|
104
|
-
# Performance monitoring
|
105
|
-
result
|
106
|
-
.on_executed { |r|
|
107
|
-
MetricsService.record_execution_time(r.task.class.name, r.runtime)
|
108
|
-
}
|
109
|
-
```
|
110
|
-
|
111
|
-
## Failure Chain Analysis
|
112
|
-
|
113
|
-
> [!IMPORTANT]
|
114
|
-
> Failure chain analysis is only available for failed results. Use these methods to trace the root cause of failures in complex task workflows.
|
115
|
-
|
116
|
-
For failed results, comprehensive failure analysis is available:
|
117
|
-
|
118
|
-
```ruby
|
119
|
-
result = ProcessOrderWorkflowTask.call(order_id: 123)
|
80
|
+
result = DeploymentWorkflow.execute(app_name: "webapp")
|
120
81
|
|
121
82
|
if result.failed?
|
122
83
|
# Find the original cause of failure
|
123
84
|
if original_failure = result.caused_failure
|
124
85
|
puts "Root cause: #{original_failure.task.class.name}"
|
125
|
-
puts "Reason: #{original_failure.
|
86
|
+
puts "Reason: #{original_failure.reason}"
|
126
87
|
end
|
127
88
|
|
128
89
|
# Find what threw the failure to this result
|
129
90
|
if throwing_task = result.threw_failure
|
130
91
|
puts "Failure source: #{throwing_task.task.class.name}"
|
92
|
+
puts "Reason: #{throwing_task.reason}"
|
131
93
|
end
|
132
94
|
|
133
95
|
# Failure classification
|
134
|
-
result.caused_failure?
|
135
|
-
result.threw_failure?
|
136
|
-
result.thrown_failure?
|
137
|
-
end
|
138
|
-
```
|
139
|
-
|
140
|
-
### Error Handling Patterns
|
141
|
-
|
142
|
-
```ruby
|
143
|
-
result = ProcessPaymentTask.call(amount: "invalid")
|
144
|
-
|
145
|
-
if result.failed?
|
146
|
-
case result.metadata[:reason]
|
147
|
-
when /validation/i
|
148
|
-
handle_validation_error(result)
|
149
|
-
when /network/i
|
150
|
-
schedule_retry(result)
|
151
|
-
else
|
152
|
-
escalate_error(result)
|
153
|
-
end
|
96
|
+
result.caused_failure? #=> true if this result was the original cause
|
97
|
+
result.threw_failure? #=> true if this result threw a failure
|
98
|
+
result.thrown_failure? #=> true if this result received a thrown failure
|
154
99
|
end
|
155
100
|
```
|
156
101
|
|
@@ -159,182 +104,90 @@ end
|
|
159
104
|
Results track their position within execution chains:
|
160
105
|
|
161
106
|
```ruby
|
162
|
-
result =
|
107
|
+
result = BuildApplication.execute(version: "1.2.3")
|
163
108
|
|
164
109
|
# Position in execution sequence
|
165
|
-
result.index
|
110
|
+
result.index #=> 0 (first task in chain)
|
166
111
|
|
167
112
|
# Access via chain
|
168
|
-
result.chain.results[result.index] == result
|
113
|
+
result.chain.results[result.index] == result #=> true
|
169
114
|
```
|
170
115
|
|
171
|
-
##
|
116
|
+
## Handlers
|
172
117
|
|
173
|
-
|
174
|
-
> Use result callbacks for clean, functional-style conditional logic. Callbacks return the result object, enabling method chaining and fluent interfaces.
|
175
|
-
|
176
|
-
Results support fluent callback patterns for conditional logic:
|
118
|
+
Use result handlers for clean, functional-style conditional logic. Handlers return the result object, enabling method chaining and fluent interfaces.
|
177
119
|
|
178
120
|
```ruby
|
179
|
-
result =
|
121
|
+
result = BuildApplication.execute(version: "1.2.3")
|
180
122
|
|
181
|
-
# Status-based
|
123
|
+
# Status-based handlers
|
182
124
|
result
|
183
|
-
.on_success { |
|
184
|
-
.on_failed { |
|
185
|
-
.on_skipped { |
|
125
|
+
.on_success { |result| notify_deployment_ready(result) }
|
126
|
+
.on_failed { |result| handle_build_failure(result) }
|
127
|
+
.on_skipped { |result| log_skip_reason(result) }
|
186
128
|
|
187
|
-
# State-based
|
129
|
+
# State-based handlers
|
188
130
|
result
|
189
|
-
.on_complete { |
|
190
|
-
.on_interrupted { |
|
131
|
+
.on_complete { |result| update_build_status(result) }
|
132
|
+
.on_interrupted { |result| cleanup_partial_artifacts(result) }
|
191
133
|
|
192
|
-
# Outcome-based
|
134
|
+
# Outcome-based handlers
|
193
135
|
result
|
194
|
-
.on_good { |
|
195
|
-
.on_bad { |
|
196
|
-
```
|
197
|
-
|
198
|
-
### Practical Callback Examples
|
199
|
-
|
200
|
-
```ruby
|
201
|
-
# Order processing pipeline
|
202
|
-
ProcessOrderTask
|
203
|
-
.call(order_id: params[:order_id])
|
204
|
-
.on_success { |result|
|
205
|
-
# Chain to notification task
|
206
|
-
SendOrderConfirmationTask.call(result.context)
|
207
|
-
}
|
208
|
-
.on_failed { |result|
|
209
|
-
# Handle specific failure types
|
210
|
-
case result.metadata[:error_type]
|
211
|
-
when "payment_declined"
|
212
|
-
redirect_to payment_retry_path
|
213
|
-
when "inventory_unavailable"
|
214
|
-
redirect_to out_of_stock_path
|
215
|
-
else
|
216
|
-
redirect_to error_path
|
217
|
-
end
|
218
|
-
}
|
219
|
-
.on_executed { |result|
|
220
|
-
# Always log performance metrics
|
221
|
-
Rails.logger.info "Order processing took #{result.runtime}s"
|
222
|
-
}
|
136
|
+
.on_good { |result| increment_success_counter(result) }
|
137
|
+
.on_bad { |result| alert_operations_team(result) }
|
223
138
|
```
|
224
139
|
|
225
140
|
## Pattern Matching
|
226
141
|
|
227
|
-
> [!NOTE]
|
228
|
-
> Pattern matching requires Ruby 3.0+. The `deconstruct` method returns `[state, status]` for array patterns, while `deconstruct_keys` provides hash access to result attributes.
|
229
|
-
|
230
142
|
Results support Ruby's pattern matching through array and hash deconstruction:
|
231
143
|
|
232
|
-
|
144
|
+
> [!IMPORTANT]
|
145
|
+
> Pattern matching requires Ruby 3.0+
|
146
|
+
|
147
|
+
### Array Pattern
|
233
148
|
|
234
149
|
```ruby
|
235
|
-
result =
|
150
|
+
result = BuildApplication.execute(version: "1.2.3")
|
236
151
|
|
237
152
|
case result
|
238
153
|
in ["complete", "success"]
|
239
|
-
redirect_to
|
154
|
+
redirect_to build_success_page
|
240
155
|
in ["interrupted", "failed"]
|
241
|
-
|
242
|
-
in ["
|
156
|
+
retry_build_with_backoff(result)
|
157
|
+
in ["interrupted", "skipped"]
|
243
158
|
log_skip_and_continue
|
244
159
|
end
|
245
160
|
```
|
246
161
|
|
247
|
-
### Hash Pattern
|
162
|
+
### Hash Pattern
|
248
163
|
|
249
164
|
```ruby
|
250
|
-
result =
|
165
|
+
result = BuildApplication.execute(version: "1.2.3")
|
251
166
|
|
252
167
|
case result
|
253
168
|
in { state: "complete", status: "success" }
|
254
|
-
|
169
|
+
celebrate_build_success
|
255
170
|
in { status: "failed", metadata: { retryable: true } }
|
256
|
-
|
171
|
+
schedule_build_retry(result)
|
257
172
|
in { bad: true, metadata: { reason: String => reason } }
|
258
|
-
|
173
|
+
escalate_build_error("Build failed: #{reason}")
|
259
174
|
end
|
260
175
|
```
|
261
176
|
|
262
|
-
### Pattern
|
177
|
+
### Pattern Guards
|
263
178
|
|
264
179
|
```ruby
|
265
180
|
case result
|
266
181
|
in { status: "failed", metadata: { attempts: n } } if n < 3
|
267
|
-
|
182
|
+
retry_build_with_delay(result, n * 2)
|
268
183
|
in { status: "failed", metadata: { attempts: n } } if n >= 3
|
269
|
-
|
184
|
+
mark_build_permanently_failed(result)
|
270
185
|
in { runtime: time } if time > performance_threshold
|
271
|
-
|
186
|
+
investigate_build_performance(result)
|
272
187
|
end
|
273
188
|
```
|
274
189
|
|
275
|
-
## Serialization and Inspection
|
276
|
-
|
277
|
-
Results provide comprehensive serialization and inspection capabilities:
|
278
|
-
|
279
|
-
### Hash Serialization
|
280
|
-
|
281
|
-
```ruby
|
282
|
-
result = ProcessOrderTask.call(order_id: 123)
|
283
|
-
|
284
|
-
result.to_h
|
285
|
-
# → {
|
286
|
-
# class: "ProcessOrderTask",
|
287
|
-
# type: "Task",
|
288
|
-
# index: 0,
|
289
|
-
# id: "abc123...",
|
290
|
-
# chain_id: "def456...",
|
291
|
-
# tags: [],
|
292
|
-
# state: "complete",
|
293
|
-
# status: "success",
|
294
|
-
# outcome: "success",
|
295
|
-
# metadata: {},
|
296
|
-
# runtime: 0.5
|
297
|
-
# }
|
298
|
-
```
|
299
|
-
|
300
|
-
### Human-Readable Inspection
|
301
|
-
|
302
|
-
```ruby
|
303
|
-
result = ProcessOrderTask.call(order_id: 123)
|
304
|
-
|
305
|
-
result.to_s
|
306
|
-
# → "ProcessOrderTask: type=Task index=0 id=abc123... state=complete status=success outcome=success metadata={} runtime=0.5"
|
307
|
-
```
|
308
|
-
|
309
|
-
### Failure Chain Serialization
|
310
|
-
|
311
|
-
> [!WARNING]
|
312
|
-
> Failed results include complete failure chain information. This data can be substantial in complex workflows - consider filtering when logging or persisting.
|
313
|
-
|
314
|
-
```ruby
|
315
|
-
failed_result = ProcessOrderWorkflowTask.call(order_id: 123)
|
316
|
-
|
317
|
-
failed_result.to_h
|
318
|
-
# → {
|
319
|
-
# # ... standard result data ...
|
320
|
-
# caused_failure: {
|
321
|
-
# class: "ValidateOrderTask",
|
322
|
-
# index: 1,
|
323
|
-
# id: "xyz789...",
|
324
|
-
# state: "interrupted",
|
325
|
-
# status: "failed"
|
326
|
-
# },
|
327
|
-
# threw_failure: {
|
328
|
-
# class: "ProcessPaymentTask",
|
329
|
-
# index: 2,
|
330
|
-
# id: "uvw123...",
|
331
|
-
# state: "interrupted",
|
332
|
-
# status: "failed"
|
333
|
-
# }
|
334
|
-
# }
|
335
|
-
```
|
336
|
-
|
337
190
|
---
|
338
191
|
|
339
192
|
- **Prev:** [Interruptions - Exceptions](../interruptions/exceptions.md)
|
340
|
-
- **Next:** [Outcomes -
|
193
|
+
- **Next:** [Outcomes - States](states.md)
|