hati-command 0.1.0.beta1 → 0.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.
- checksums.yaml +4 -4
- data/README.md +174 -47
- data/hati-command.gemspec +3 -3
- data/lib/hati_command/befehl.rb +91 -18
- data/lib/hati_command/callee.rb +0 -2
- data/lib/hati_command/cmd.rb +2 -2
- data/lib/hati_command/errors/base_error.rb +35 -0
- data/lib/hati_command/errors/configuration_error.rb +12 -0
- data/lib/hati_command/errors/fail_fast_error.rb +4 -22
- data/lib/hati_command/errors/transaction_error.rb +12 -0
- data/lib/hati_command/result.rb +1 -1
- data/lib/hati_command/version.rb +1 -1
- data/lib/hati_command.rb +4 -0
- metadata +12 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44f1b8b3fa48fbee4ab3670fcb0f5f049a1ceb42fa875b13592facfe3ea2b7f5
|
4
|
+
data.tar.gz: 197491d0ed328d16ba627bc5900b360c42982e2b697b351e78fc30d512c25606
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61aa3b06315beb6a2fb716a98d4322d90e4fd602a702a0cf950a4760938aaa084705bb858570cbd4dd647332b164e57e3d3ef7758595a3d2505417ce057a3e99
|
7
|
+
data.tar.gz: 8296ba06921e87df95911bf10e56995f8d419aebe9d5dd2ff5f973db341025c3fe278362b4ba269646715a7f97b1106f90b6242a4f9a96531314f6a9e5307931
|
data/README.md
CHANGED
@@ -24,15 +24,19 @@ The `hati-command` gem is designed to simplify command execution, emphasizing ef
|
|
24
24
|
- [Handling Failure](#handling-failure)
|
25
25
|
- [Transactional Behavior](#transactional-behavior-fail-fast-with-failure)
|
26
26
|
- [Advanced Usage](#advanced-usage)
|
27
|
+
|
27
28
|
- [Result Customization](#result-customization)
|
28
29
|
- [meta](#meta)
|
29
30
|
- [error](#error)
|
30
31
|
- [trace](#trace)
|
31
32
|
- [Command Configurations](#command-configurations)
|
33
|
+
- [result_inference](#result_inference)
|
34
|
+
- [call_as](#call_as)
|
32
35
|
- [failure](#failure)
|
33
36
|
- [fail_fast](#fail_fast)
|
34
37
|
- [unexpected_err](#unexpected_err)
|
35
|
-
- [
|
38
|
+
- [ar_transaction](#ar_transaction)
|
39
|
+
|
36
40
|
- [Development](#development)
|
37
41
|
- [Contributing](#contributing)
|
38
42
|
- [License](#license)
|
@@ -54,7 +58,13 @@ gem install hati-command
|
|
54
58
|
|
55
59
|
## Basic Usage
|
56
60
|
|
57
|
-
To use the `hati-command` gem, you can create a command class that includes the `HatiCommand::Cmd` module.
|
61
|
+
To use the `hati-command` gem, you can create a command class that includes the `HatiCommand::Cmd` module.
|
62
|
+
|
63
|
+
Note: No need to nest object APIs under `private` as popular template for `Servie Object` designs
|
64
|
+
|
65
|
+
only main caller method is public by design
|
66
|
+
|
67
|
+
#### Example
|
58
68
|
|
59
69
|
```ruby
|
60
70
|
require 'hati_command'
|
@@ -79,6 +89,13 @@ class GreetingCommand
|
|
79
89
|
end
|
80
90
|
```
|
81
91
|
|
92
|
+
### Command `API`
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
result = GreetingCommand.call("Hello, World!") # Outputs: Result
|
96
|
+
result = GreetingCommand.new # Outputs: private method `new' called
|
97
|
+
```
|
98
|
+
|
82
99
|
### Handling `Success`
|
83
100
|
|
84
101
|
```ruby
|
@@ -92,7 +109,6 @@ puts result.failure # Outputs: nil
|
|
92
109
|
|
93
110
|
puts result.value # Outputs: "HELLO, WORLD!"
|
94
111
|
puts result.result # Outputs: HatiCommand::Success
|
95
|
-
|
96
112
|
```
|
97
113
|
|
98
114
|
### Handling `Failure`
|
@@ -249,11 +265,97 @@ puts result.trace # Outputs: path/to/cmds/doomed_command.rb:5:in `call'
|
|
249
265
|
|
250
266
|
Provides options for default failure message or errors. Available configs are:
|
251
267
|
|
252
|
-
- `
|
253
|
-
- `
|
254
|
-
- `
|
255
|
-
- `
|
256
|
-
- `
|
268
|
+
- `result_inference`(Bool(true)) => implicit Result wrapper
|
269
|
+
- `call_as`(Symbol[:call]) => Main call method name
|
270
|
+
- `failure`(String | ErrorClass) => Message or Error
|
271
|
+
- `fail_fast`(String || ErrorClass) => Message or Error
|
272
|
+
- `unexpected_err`(Bool[true]) => Message or Error
|
273
|
+
|
274
|
+
#### Experimental:
|
275
|
+
|
276
|
+
- `ar_transaction`(Array[Symbol], returnable: Bool[true]) => methods to wrap in Transaction, requires 'activerecord'
|
277
|
+
|
278
|
+
```ruby
|
279
|
+
class AppService
|
280
|
+
include HatiCommand::Cmd
|
281
|
+
|
282
|
+
command do
|
283
|
+
result_inference true
|
284
|
+
call_as :perform
|
285
|
+
failure "Default Error"
|
286
|
+
fail_fast "Default Fail Fast Error"
|
287
|
+
unexpected_err BaseServiceError
|
288
|
+
end
|
289
|
+
|
290
|
+
# ...
|
291
|
+
end
|
292
|
+
|
293
|
+
class PaymentService < AppService
|
294
|
+
command do
|
295
|
+
ar_transaction :perform # WIP: Experimental
|
296
|
+
unexpected_err PaymentServiceTechnicalError
|
297
|
+
end
|
298
|
+
|
299
|
+
def perform(params)
|
300
|
+
account = Account.lock.find(user_id)
|
301
|
+
Failure("User account is inactive") unless user.active?
|
302
|
+
|
303
|
+
CreditTransaction.create!(user_id: user.id, amount: amount)
|
304
|
+
AuditLog.create!(action: 'add_funds', account: account)
|
305
|
+
|
306
|
+
Success('Funds has been add to account')
|
307
|
+
end
|
308
|
+
|
309
|
+
# ...
|
310
|
+
end
|
311
|
+
|
312
|
+
```
|
313
|
+
|
314
|
+
### result_inference
|
315
|
+
|
316
|
+
```ruby
|
317
|
+
class GreetingCommand
|
318
|
+
include HatiCommand::Cmd
|
319
|
+
|
320
|
+
command do
|
321
|
+
result_inference true # Implicitly wraps non-Result as Success
|
322
|
+
end
|
323
|
+
|
324
|
+
def call
|
325
|
+
42
|
326
|
+
end
|
327
|
+
# ...
|
328
|
+
end
|
329
|
+
```
|
330
|
+
|
331
|
+
```ruby
|
332
|
+
result = GreetingCommand.call
|
333
|
+
puts result.success # Outputs: 42
|
334
|
+
puts result.failure? # Outputs: false
|
335
|
+
```
|
336
|
+
|
337
|
+
### call_as
|
338
|
+
|
339
|
+
```ruby
|
340
|
+
class GreetingCommand
|
341
|
+
include HatiCommand::Cmd
|
342
|
+
|
343
|
+
command do
|
344
|
+
call_as :execute # E.q. :perform, :run, etc.
|
345
|
+
end
|
346
|
+
|
347
|
+
def execute
|
348
|
+
Success(42)
|
349
|
+
end
|
350
|
+
# ...
|
351
|
+
end
|
352
|
+
```
|
353
|
+
|
354
|
+
```ruby
|
355
|
+
result = GreetingCommand.execute
|
356
|
+
puts result.success # Outputs: 42
|
357
|
+
puts result.failure? # Outputs: false
|
358
|
+
```
|
257
359
|
|
258
360
|
### failure
|
259
361
|
|
@@ -276,9 +378,11 @@ Provides options for default failure message or errors. Available configs are:
|
|
276
378
|
16| end
|
277
379
|
```
|
278
380
|
|
381
|
+
NOTE: not configured fail fast uses default error
|
382
|
+
|
279
383
|
```ruby
|
280
384
|
result = DoomedCommand.call(fail_fast: true)
|
281
|
-
|
385
|
+
|
282
386
|
puts result.failure # Outputs: nil
|
283
387
|
puts result.error # Outputs: "Default Error"
|
284
388
|
puts result.trace # Outputs: path/to/cmds/doomed_command.rb:5:in `call'
|
@@ -360,59 +464,82 @@ puts result.trace # Outputs: path/to/cmds/greeting_command.rb:9:in `call'
|
|
360
464
|
14| end
|
361
465
|
```
|
362
466
|
|
467
|
+
NOTE: Original error becomes value (failure)
|
468
|
+
|
363
469
|
```ruby
|
364
470
|
result = GreetingCommand.call
|
365
|
-
# NOTE: Original error becomes value (failure)
|
366
|
-
puts result.failure # Outputs: TypeError: no implicit conversion of Integer into String
|
367
471
|
|
472
|
+
puts result.failure # Outputs: TypeError: no implicit conversion of Integer into String
|
368
473
|
puts result.error # Outputs: GreetingError
|
369
474
|
puts result.trace # Outputs: path/to/cmds/greeting_command.rb:12:in `call'
|
370
475
|
```
|
371
476
|
|
372
|
-
|
477
|
+
## Experimental
|
373
478
|
|
374
|
-
|
375
|
-
1 | class GreetingCommand
|
376
|
-
2 | include HatiCommand::Cmd
|
377
|
-
3 |
|
378
|
-
4 | command do
|
379
|
-
5 | result_inference true # Implicitly wraps non-Result as Success
|
380
|
-
5 | end
|
381
|
-
6 |
|
382
|
-
7 | def call
|
383
|
-
8 | 42
|
384
|
-
9 | end
|
385
|
-
10| # ...
|
386
|
-
11| end
|
387
|
-
```
|
479
|
+
### ar_transaction
|
388
480
|
|
389
|
-
|
390
|
-
|
391
|
-
puts result.success # Outputs: 42
|
392
|
-
puts result.failure? # Outputs: false
|
393
|
-
```
|
481
|
+
Wraps listed methods in Transaction with blocking non-Result returns.
|
482
|
+
At this dev stage relies on 'activerecord'
|
394
483
|
|
395
|
-
|
484
|
+
- NOTE: considering extensicve expirience of usage, we recomend to use some naming convention
|
485
|
+
across codebase for such methods, to keep healthy Elegance-to-Explicitness ratio
|
486
|
+
|
487
|
+
#### E.g. suffixes: \_flow, \_transaction, \_task, etc.
|
488
|
+
|
489
|
+
- NOTE: `Failure()` works as transaction break, returns only from called method's as Result (Failure) object
|
490
|
+
|
491
|
+
- NOTE: `Failure!()` works on Service level same fail_fast immediately halts execution, return from
|
492
|
+
|
493
|
+
- NOTE: Unlike `ActiveRecord::Transaction` Implicit non-Result returns will trigger `TransactionError`,
|
494
|
+
blocking partial commit state unless:
|
396
495
|
|
397
496
|
```ruby
|
398
|
-
|
399
|
-
2 | include HatiCommand::Cmd
|
400
|
-
3 |
|
401
|
-
4 | command do
|
402
|
-
5 | call_as :execute # E.q. :perform, :run, etc.
|
403
|
-
5 | end
|
404
|
-
6 |
|
405
|
-
7 | def execute
|
406
|
-
8 | Success(42)
|
407
|
-
9 | end
|
408
|
-
10| # ...
|
409
|
-
11| end
|
497
|
+
ar_transaction :transactional_method_name, returnable: false # Defaults to true
|
410
498
|
```
|
411
499
|
|
500
|
+
### Pseudo-Example:
|
501
|
+
|
412
502
|
```ruby
|
413
|
-
|
414
|
-
|
415
|
-
|
503
|
+
class PaymentService < AppService
|
504
|
+
command do
|
505
|
+
ar_transaction :add_funds_transaction
|
506
|
+
unexpected_err PaymentServiceTechnicalError
|
507
|
+
end
|
508
|
+
|
509
|
+
def call(params)
|
510
|
+
amount = currency_exchange(params[:amount])
|
511
|
+
debit_transaction = add_funds_transaction(amount)
|
512
|
+
|
513
|
+
return debit_transaction if debit_transaction.success?
|
514
|
+
|
515
|
+
Failure(debit_transaction, err: 'Unable to add funds')
|
516
|
+
end
|
517
|
+
|
518
|
+
def currency_exchange
|
519
|
+
# ...
|
520
|
+
end
|
521
|
+
|
522
|
+
# Whole method evaluates in ActiveRecord::Transaction block
|
523
|
+
def add_funds_transaction(amount)
|
524
|
+
account = Account.lock.find(user_id)
|
525
|
+
Failure("User account is inactive") unless user.active?
|
526
|
+
|
527
|
+
# Fires TransactionError, unless :returnable configuration is disabled
|
528
|
+
return 'I am an Error'
|
529
|
+
|
530
|
+
user.balance += amount
|
531
|
+
user.save
|
532
|
+
Failure('Account debit issue') if user.errors
|
533
|
+
|
534
|
+
CreditTransaction.create!(user_id: user.id, amount: amount)
|
535
|
+
AuditLog.create!(action: 'add_funds', account: account)
|
536
|
+
|
537
|
+
# NOTE: result inference won't work, use only Result objects
|
538
|
+
Success('Great Succeess')
|
539
|
+
end
|
540
|
+
|
541
|
+
# ...
|
542
|
+
end
|
416
543
|
```
|
417
544
|
|
418
545
|
## Authors
|
data/hati-command.gemspec
CHANGED
@@ -8,12 +8,12 @@ require 'hati_command/version'
|
|
8
8
|
Gem::Specification.new do |spec|
|
9
9
|
spec.name = 'hati-command'
|
10
10
|
spec.version = HatiCommand::VERSION
|
11
|
-
spec.authors =
|
11
|
+
spec.authors = ['Mariya Giy', 'Yuri Gi']
|
12
12
|
spec.email = %w[yurigi.pro@gmail.com giy.mariya@gmail.com]
|
13
13
|
spec.license = 'MIT'
|
14
14
|
|
15
|
-
spec.summary = 'A Ruby gem for creating
|
16
|
-
spec.description = 'hati-command is a Ruby gem for implementing
|
15
|
+
spec.summary = 'A Ruby gem for creating Service objects, Command pattern, and Interactors with result handling.'
|
16
|
+
spec.description = 'hati-command is a Ruby gem for implementing Service objects, Command pattern and Interactors with result handling.'
|
17
17
|
spec.homepage = "https://github.com/hackico-ai/#{spec.name}"
|
18
18
|
|
19
19
|
spec.required_ruby_version = '>= 3.0.0'
|
data/lib/hati_command/befehl.rb
CHANGED
@@ -23,6 +23,9 @@ module HatiCommand
|
|
23
23
|
# Provides class methods for command configuration and execution.
|
24
24
|
# These methods are automatically added to any class that extends Befehl.
|
25
25
|
module BefehlClassMethods
|
26
|
+
# @module namespace as alias
|
27
|
+
ERR = HatiCommand::Errors
|
28
|
+
|
26
29
|
# Configures a command block with specific settings
|
27
30
|
# @yield [void] The configuration block
|
28
31
|
# @return [Hash] The command configuration
|
@@ -32,52 +35,99 @@ module HatiCommand
|
|
32
35
|
# fail_fast true
|
33
36
|
# end
|
34
37
|
def command(&block)
|
35
|
-
@__command_config ||= { call_as: :call }
|
36
38
|
instance_eval(&block) if block_given?
|
37
39
|
end
|
38
40
|
|
39
|
-
# Retrieves the current command configuration
|
40
41
|
# @return [Hash] The current command configuration settings
|
41
42
|
def command_config
|
42
|
-
|
43
|
+
__command_config
|
43
44
|
end
|
44
45
|
|
45
46
|
# Sets the result inference behavior for the command.
|
46
47
|
# @param value [Boolean] Indicates whether to enable result inference.
|
47
48
|
# @return [void]
|
48
49
|
def result_inference(value)
|
49
|
-
|
50
|
+
command_config[:result_inference] = value
|
50
51
|
end
|
51
52
|
|
52
53
|
# Sets the failure handler for the command
|
53
54
|
# @param value [Symbol, Proc] The failure handler to be used
|
54
55
|
# @return [void]
|
55
56
|
def failure(value)
|
56
|
-
|
57
|
+
command_config[:failure] = value
|
57
58
|
end
|
58
59
|
|
59
60
|
# Sets the fail-fast behavior for the command
|
60
61
|
# @param value [Boolean] Whether to enable fail-fast behavior
|
61
62
|
# @return [void]
|
62
63
|
def fail_fast(value)
|
63
|
-
|
64
|
+
command_config[:fail_fast] = value
|
64
65
|
end
|
65
66
|
|
66
67
|
# Sets the unexpected error handler for the command
|
67
68
|
# @param value [Symbol, Proc, Boolean] The error handler to be used
|
68
69
|
# @return [void]
|
69
70
|
def unexpected_err(value)
|
70
|
-
|
71
|
+
command_config[:unexpected_err] = value
|
71
72
|
end
|
72
73
|
|
73
74
|
# This method checks if a caller method has been set; if not, it defaults to `:call`.
|
74
75
|
# @return [Symbol] The name of the method to call.
|
75
76
|
def call_as(value = :call)
|
76
|
-
|
77
|
+
command_config[:call_as] = value
|
77
78
|
|
78
79
|
singleton_class.send(:alias_method, value, :call)
|
79
80
|
end
|
80
81
|
|
82
|
+
# WIP: experimental
|
83
|
+
# TODO: set of methods
|
84
|
+
def ar_transaction(*cmd_methods, returnable: true)
|
85
|
+
has_ar_defined = defined?(ActiveRecord::Base) && ActiveRecord::Base.respond_to?(:transaction)
|
86
|
+
raise ERR::ConfigurationError, 'No ActiveRecord defined' unless has_ar_defined
|
87
|
+
|
88
|
+
has_valid_mthds = cmd_methods.any? { |value| value.is_a?(Symbol) }
|
89
|
+
raise ERR::ConfigurationError, 'Invalid types. Accepts Array[Symbol]' unless has_valid_mthds
|
90
|
+
|
91
|
+
command_config[:ar_transaction] = {
|
92
|
+
methods: cmd_methods,
|
93
|
+
returnable: returnable
|
94
|
+
}
|
95
|
+
|
96
|
+
dynamic_module = Module.new do
|
97
|
+
cmd_methods.each do |method_name|
|
98
|
+
define_method(method_name) do |*args, **kwargs, &block|
|
99
|
+
rez = ActiveRecord::Base.transaction do
|
100
|
+
result = super(*args, **kwargs, &block)
|
101
|
+
|
102
|
+
# Rollbacks to prevent partial transaction state
|
103
|
+
if returnable && !result.is_a?(HatiCommand::Result)
|
104
|
+
raise ERR::ConfigurationError,
|
105
|
+
'This command configuration requires explicit Result-return from transaction'
|
106
|
+
end
|
107
|
+
|
108
|
+
# Allows explicit partial commit
|
109
|
+
if result.failure?
|
110
|
+
raise ERR::TransactionError.new('Transaction brake has been triggered', failure_obj: result.value)
|
111
|
+
end
|
112
|
+
|
113
|
+
result
|
114
|
+
end
|
115
|
+
|
116
|
+
rez
|
117
|
+
rescue ERR::TransactionError => e
|
118
|
+
# TODO: process trace corectly (line of code)
|
119
|
+
HatiCommand::Failure.new(e.failure_obj, err: e.message, trace: e.backtrace&.first)
|
120
|
+
# Every other error including FailFast goes to main caller method
|
121
|
+
rescue ActiveRecord::ActiveRecordError => e
|
122
|
+
# TODO: process trace
|
123
|
+
HatiCommand::Failure.new(e, err: e.message, trace: e.backtrace&.first)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
prepend dynamic_module
|
129
|
+
end
|
130
|
+
|
81
131
|
# Executes the command with the given arguments.
|
82
132
|
#
|
83
133
|
# This method creates a new instance of the command class, yields it to an optional block,
|
@@ -86,36 +136,53 @@ module HatiCommand
|
|
86
136
|
#
|
87
137
|
# @param args [Array] Arguments to be passed to the instance method.
|
88
138
|
# @yield [Object] Optional block that yields the new instance for additional configuration.
|
89
|
-
# @return [HatiCommand::Result, Object] The result of the command
|
139
|
+
# @return [HatiCommand::Result, Object] The result of the command, wrapped in a Result object if applicable.
|
90
140
|
# @raise [HatiCommand::Errors::FailFastError] If a fail-fast condition is triggered.
|
91
141
|
# @raise [StandardError] If an unexpected error occurs and no handler is configured.
|
92
|
-
def call(
|
93
|
-
|
94
|
-
|
95
|
-
yield(obj) if block_given?
|
142
|
+
def call(*args, __command_reciever: nil, **kwargs, &block)
|
143
|
+
result = caller_result(*args, __command_reciever: __command_reciever, **kwargs, &block)
|
96
144
|
|
97
|
-
result = obj.send(command_config[:call_as], ...)
|
98
145
|
return result unless command_config[:result_inference]
|
99
146
|
return result if result.is_a?(HatiCommand::Result)
|
100
147
|
|
101
148
|
HatiCommand::Success.new(result)
|
102
|
-
rescue
|
149
|
+
rescue ERR::FailFastError => e
|
103
150
|
handle_fail_fast_error(e)
|
104
151
|
rescue StandardError => e
|
105
152
|
handle_standard_error(e)
|
106
153
|
end
|
107
154
|
|
155
|
+
# TODO: think on opts to hide reciever
|
156
|
+
def caller_result(*args, __command_reciever: nil, **kwargs, &block)
|
157
|
+
# expecting pre-configured reciever if given
|
158
|
+
if __command_reciever
|
159
|
+
obj = __command_reciever
|
160
|
+
else
|
161
|
+
obj = new
|
162
|
+
yield(obj) if !obj && block_given?
|
163
|
+
end
|
164
|
+
|
165
|
+
# TODO: add error if no instance method to call
|
166
|
+
obj.send(command_config[:call_as] || :call, *args, **kwargs, &block)
|
167
|
+
end
|
168
|
+
|
108
169
|
module_function
|
109
170
|
|
171
|
+
# @return [Hash] The current command configuration settings
|
172
|
+
# @api private
|
173
|
+
def __command_config
|
174
|
+
@__command_config ||= {}
|
175
|
+
end
|
176
|
+
|
110
177
|
# Handles fail-fast errors during command execution
|
111
178
|
# @param error [HatiCommand::Errors::FailFastError] The fail-fast error to handle
|
112
179
|
# @return [HatiCommand::Failure] A failure object containing error details
|
113
180
|
# @api private
|
114
181
|
def handle_fail_fast_error(error)
|
115
|
-
|
116
|
-
return HatiCommand::Failure.new(error, trace: error.backtrace.first) unless
|
182
|
+
failure_obj = error.failure_obj
|
183
|
+
return HatiCommand::Failure.new(error, trace: error.backtrace.first) unless failure_obj
|
117
184
|
|
118
|
-
|
185
|
+
failure_obj.tap { |err| err.trace = error.backtrace[1] }
|
119
186
|
end
|
120
187
|
|
121
188
|
# Handles standard errors during command execution
|
@@ -130,6 +197,12 @@ module HatiCommand
|
|
130
197
|
err = internal_err.is_a?(TrueClass) ? error : internal_err
|
131
198
|
HatiCommand::Failure.new(error, err: err, trace: error.backtrace.first)
|
132
199
|
end
|
200
|
+
|
201
|
+
def execute_with_transaction_handling?
|
202
|
+
has_ar_defined = defined?(ActiveRecord::Base) && ActiveRecord::Base.respond_to?(:transaction)
|
203
|
+
|
204
|
+
!!(command_config.dig(:ar_transaction, :methods) && has_ar_defined)
|
205
|
+
end
|
133
206
|
end
|
134
207
|
end
|
135
208
|
end
|
data/lib/hati_command/callee.rb
CHANGED
data/lib/hati_command/cmd.rb
CHANGED
@@ -73,8 +73,8 @@ module HatiCommand
|
|
73
73
|
default_error = self.class.command_config[:fail_fast] || self.class.command_config[:failure]
|
74
74
|
error = err || default_error
|
75
75
|
|
76
|
-
|
77
|
-
raise HatiCommand::Errors::FailFastError.new('Fail Fast Triggered',
|
76
|
+
failure_obj = HatiCommand::Failure.new(value, err: error, meta: meta)
|
77
|
+
raise HatiCommand::Errors::FailFastError.new('Fail Fast Triggered', failure_obj: failure_obj)
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HatiCommand
|
4
|
+
module Errors
|
5
|
+
# Custom BaseError class for command issues scenarios in HatiCommand
|
6
|
+
#
|
7
|
+
# @example Raising a BaseError with a message
|
8
|
+
# raise HatiCommand::Error::BaseError, "Operation failed"
|
9
|
+
class BaseError < StandardError
|
10
|
+
DEFAULT_MSG = 'Default message: Oooops! Something went wrong. Please check the logs.'
|
11
|
+
|
12
|
+
attr_reader :failure_obj
|
13
|
+
|
14
|
+
# @param message [String] The error message
|
15
|
+
# @param failure_obj [Object] An optional Error || Failure DTO
|
16
|
+
def initialize(message = nil, failure_obj: nil)
|
17
|
+
msg = build_msg + (message || default_message)
|
18
|
+
super(msg)
|
19
|
+
@failure_obj = failure_obj
|
20
|
+
end
|
21
|
+
|
22
|
+
def error_klass
|
23
|
+
self.class.name
|
24
|
+
end
|
25
|
+
|
26
|
+
def build_msg
|
27
|
+
"[#{error_klass}] "
|
28
|
+
end
|
29
|
+
|
30
|
+
def default_message
|
31
|
+
DEFAULT_MSG
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -2,28 +2,10 @@
|
|
2
2
|
|
3
3
|
module HatiCommand
|
4
4
|
module Errors
|
5
|
-
# Custom error class for
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
#
|
10
|
-
# @example Raising a FailFastError with a message and error object
|
11
|
-
# begin
|
12
|
-
# # Some operation that might fail
|
13
|
-
# rescue StandardError => e
|
14
|
-
# raise HatiCommand::FailFastError.new("Operation failed", err_obj: e)
|
15
|
-
# end
|
16
|
-
class FailFastError < StandardError
|
17
|
-
# @return [Object] The associated error object
|
18
|
-
attr_reader :err_obj
|
19
|
-
|
20
|
-
# Initialize a new FailFastError
|
21
|
-
#
|
22
|
-
# @param message [String] The error message
|
23
|
-
# @param err_obj [Object] An optional error object associated with this error
|
24
|
-
def initialize(message, err_obj: nil)
|
25
|
-
super(message)
|
26
|
-
@err_obj = err_obj
|
5
|
+
# Custom error class for FailFast scenario in HatiCommand
|
6
|
+
class FailFastError < BaseError
|
7
|
+
def default_message
|
8
|
+
'Halt Execution'
|
27
9
|
end
|
28
10
|
end
|
29
11
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HatiCommand
|
4
|
+
module Errors
|
5
|
+
# Custom error class for Transaction issue scenarios in HatiCommand
|
6
|
+
class TransactionError < BaseError
|
7
|
+
def default_message
|
8
|
+
'Transaction Error has been triggerd'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/hati_command/result.rb
CHANGED
@@ -43,7 +43,7 @@ module HatiCommand
|
|
43
43
|
# @return [Array<String>, nil] Execution trace information for debugging
|
44
44
|
class Result
|
45
45
|
attr_reader :value, :meta
|
46
|
-
attr_accessor :trace
|
46
|
+
attr_accessor :trace, :err
|
47
47
|
|
48
48
|
# Initializes a new Result instance with a value and optional context.
|
49
49
|
#
|
data/lib/hati_command/version.rb
CHANGED
data/lib/hati_command.rb
CHANGED
@@ -2,7 +2,10 @@
|
|
2
2
|
|
3
3
|
require 'hati_command/version'
|
4
4
|
# errors
|
5
|
+
require 'hati_command/errors/base_error'
|
6
|
+
require 'hati_command/errors/configuration_error'
|
5
7
|
require 'hati_command/errors/fail_fast_error'
|
8
|
+
require 'hati_command/errors/transaction_error'
|
6
9
|
# result
|
7
10
|
require 'hati_command/result'
|
8
11
|
require 'hati_command/success'
|
@@ -10,4 +13,5 @@ require 'hati_command/failure'
|
|
10
13
|
# core
|
11
14
|
require 'hati_command/callee'
|
12
15
|
require 'hati_command/befehl'
|
16
|
+
# cmd
|
13
17
|
require 'hati_command/cmd'
|
metadata
CHANGED
@@ -1,18 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hati-command
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
8
|
-
-
|
9
|
-
autorequire:
|
7
|
+
- Mariya Giy
|
8
|
+
- Yuri Gi
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
13
12
|
dependencies: []
|
14
|
-
description: hati-command is a Ruby gem for implementing
|
15
|
-
result handling.
|
13
|
+
description: hati-command is a Ruby gem for implementing Service objects, Command
|
14
|
+
pattern and Interactors with result handling.
|
16
15
|
email:
|
17
16
|
- yurigi.pro@gmail.com
|
18
17
|
- giy.mariya@gmail.com
|
@@ -27,7 +26,10 @@ files:
|
|
27
26
|
- lib/hati_command/befehl.rb
|
28
27
|
- lib/hati_command/callee.rb
|
29
28
|
- lib/hati_command/cmd.rb
|
29
|
+
- lib/hati_command/errors/base_error.rb
|
30
|
+
- lib/hati_command/errors/configuration_error.rb
|
30
31
|
- lib/hati_command/errors/fail_fast_error.rb
|
32
|
+
- lib/hati_command/errors/transaction_error.rb
|
31
33
|
- lib/hati_command/failure.rb
|
32
34
|
- lib/hati_command/result.rb
|
33
35
|
- lib/hati_command/success.rb
|
@@ -43,7 +45,6 @@ metadata:
|
|
43
45
|
source_code_uri: https://github.com/hackico-ai/hati-command
|
44
46
|
bug_tracker_uri: https://github.com/hackico-ai/hati-command/issues
|
45
47
|
rubygems_mfa_required: 'true'
|
46
|
-
post_install_message:
|
47
48
|
rdoc_options: []
|
48
49
|
require_paths:
|
49
50
|
- lib
|
@@ -58,8 +59,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
58
59
|
- !ruby/object:Gem::Version
|
59
60
|
version: '0'
|
60
61
|
requirements: []
|
61
|
-
rubygems_version: 3.
|
62
|
-
signing_key:
|
62
|
+
rubygems_version: 3.6.9
|
63
63
|
specification_version: 4
|
64
|
-
summary: A Ruby gem for creating
|
64
|
+
summary: A Ruby gem for creating Service objects, Command pattern, and Interactors
|
65
|
+
with result handling.
|
65
66
|
test_files: []
|