u-case 5.2.1 → 5.3.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 +31 -0
- data/README.pt-BR.md +31 -0
- data/lib/micro/case/config.rb +10 -0
- data/lib/micro/case/error.rb +9 -0
- data/lib/micro/case/result.rb +4 -0
- data/lib/micro/case/safe.rb +8 -0
- data/lib/micro/case/version.rb +1 -1
- data/lib/micro/case.rb +1 -1
- data/lib/micro/cases.rb +4 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 68a2fca8a1808ae9a30ffcdca77631507d89de9fd070628442a9860ce1000fc3
|
|
4
|
+
data.tar.gz: bcdfdac58fd882e5ed1f912e29d8decbf83971638e43acfe62e84a8697530dc9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ef37188a66960746af6613e98c259198e489afb75f25821d15b91cf24cc485b1153f05a80745f702e158f0fcbb0cd84733bccf7fefb0581f03d3c81dbbd69a69
|
|
7
|
+
data.tar.gz: a89891142cbe3be3cc36ac5cdd22f257d164c47ff1b1a484768b76b9f199590dfb10725985369080a73105db23f42a2d5401ab0a6cd8f977df1cc8b9873e92aa
|
data/README.md
CHANGED
|
@@ -60,6 +60,7 @@ unreleased| https://github.com/serradura/u-case/blob/main/README.md
|
|
|
60
60
|
- [`Micro::Case::Safe` - Is there some feature to auto handle exceptions inside of a use case or flow?](#microcasesafe---is-there-some-feature-to-auto-handle-exceptions-inside-of-a-use-case-or-flow)
|
|
61
61
|
- [`Micro::Cases::Safe::Flow`](#microcasessafeflow)
|
|
62
62
|
- [`Micro::Case::Result#on_exception`](#microcaseresulton_exception)
|
|
63
|
+
- [Opting out of the safe mechanism](#opting-out-of-the-safe-mechanism)
|
|
63
64
|
- [Validating attributes with `accept:` / `reject:`](#validating-attributes-with-accept--reject)
|
|
64
65
|
- [`u-case/with_activemodel_validation` - How to validate the use case attributes?](#u-casewith_activemodel_validation---how-to-validate-the-use-case-attributes)
|
|
65
66
|
- [If I enabled the auto validation, is it possible to disable it only in specific use cases?](#if-i-enabled-the-auto-validation-is-it-possible-to-disable-it-only-in-specific-use-cases)
|
|
@@ -1070,6 +1071,28 @@ As you can see, this hook has the same behavior of `result.on_failure(:exception
|
|
|
1070
1071
|
|
|
1071
1072
|
[⬆️ Back to Top](#table-of-contents-)
|
|
1072
1073
|
|
|
1074
|
+
#### Opting out of the safe mechanism
|
|
1075
|
+
|
|
1076
|
+
The "safe" mechanism is opinionated: it converts any unhandled exception inside a use case (or any step of a flow) into a failure result with `type: :exception`. That is powerful, but it can also produce a **fragmented codebase**, where some exceptions are handled with `rescue` inside `call!` and others are handled later via `on_exception` / `on_failure(:exception)` — making the control flow hard to reason about.
|
|
1077
|
+
|
|
1078
|
+
If you prefer a single, explicit convention for exception handling — namely, plain `rescue` statements inside your use cases — you can disable the safe APIs entirely:
|
|
1079
|
+
|
|
1080
|
+
```ruby
|
|
1081
|
+
Micro::Case.config do |config|
|
|
1082
|
+
config.disable_safe_features = true
|
|
1083
|
+
end
|
|
1084
|
+
```
|
|
1085
|
+
|
|
1086
|
+
Once enabled, the following will raise `Micro::Case::Error::SafeFeaturesDisabled`, ensuring no one in the codebase can reintroduce the safe path by accident:
|
|
1087
|
+
|
|
1088
|
+
- Subclassing `Micro::Case::Safe`
|
|
1089
|
+
- Calling `Micro::Cases.safe_flow(...)`
|
|
1090
|
+
- Calling `Micro::Case::Result#on_exception`
|
|
1091
|
+
|
|
1092
|
+
See [`Micro::Case.config`](#microcaseconfig) for the full list of available toggles.
|
|
1093
|
+
|
|
1094
|
+
[⬆️ Back to Top](#table-of-contents-)
|
|
1095
|
+
|
|
1073
1096
|
### Validating attributes with `accept:` / `reject:`
|
|
1074
1097
|
|
|
1075
1098
|
Since `u-case 5.2.0`, every use case includes the [`accept` extension](https://github.com/serradura/u-attributes#accept-extension) from [`u-attributes`](https://github.com/serradura/u-attributes) (requires `u-attributes >= 2.8`). You can declare type expectations (or any other check) directly on the attribute, and the use case will fail automatically with the `:invalid_attributes` type when any attribute is rejected — no need to validate inside `call!`.
|
|
@@ -1225,6 +1248,14 @@ Micro::Case.config do |config|
|
|
|
1225
1248
|
|
|
1226
1249
|
# Use to enable/disable the `Micro::Case::Results#transitions`.
|
|
1227
1250
|
config.enable_transitions = true
|
|
1251
|
+
|
|
1252
|
+
# Use to forbid the "safe" features and ensure a single way to handle exceptions
|
|
1253
|
+
# (via standard `rescue` statements). When set to `true`, the following will raise
|
|
1254
|
+
# `Micro::Case::Error::SafeFeaturesDisabled`:
|
|
1255
|
+
# - Subclassing `Micro::Case::Safe`
|
|
1256
|
+
# - Calling `Micro::Cases.safe_flow(...)`
|
|
1257
|
+
# - Calling `Micro::Case::Result#on_exception`
|
|
1258
|
+
config.disable_safe_features = false
|
|
1228
1259
|
end
|
|
1229
1260
|
```
|
|
1230
1261
|
|
data/README.pt-BR.md
CHANGED
|
@@ -58,6 +58,7 @@ unreleased| https://github.com/serradura/u-case/blob/main/README.md
|
|
|
58
58
|
- [`Micro::Case::Safe` - Existe algum recurso para lidar automaticamente com exceções dentro de um caso de uso ou fluxo?](#microcasesafe---existe-algum-recurso-para-lidar-automaticamente-com-exceções-dentro-de-um-caso-de-uso-ou-fluxo)
|
|
59
59
|
- [`Micro::Cases::Safe::Flow`](#microcasessafeflow)
|
|
60
60
|
- [`Micro::Case::Result#on_exception`](#microcaseresulton_exception)
|
|
61
|
+
- [Desabilitando o mecanismo "safe"](#desabilitando-o-mecanismo-safe)
|
|
61
62
|
- [Validando atributos com `accept:` / `reject:`](#validando-atributos-com-accept--reject)
|
|
62
63
|
- [`u-case/with_activemodel_validation` - Como validar os atributos do caso de uso?](#u-casewith_activemodel_validation---como-validar-os-atributos-do-caso-de-uso)
|
|
63
64
|
- [Se eu habilitei a validação automática, é possível desabilitá-la apenas em casos de uso específicos?](#se-eu-habilitei-a-validação-automática-é-possível-desabilitá-la-apenas-em-casos-de-uso-específicos)
|
|
@@ -1071,6 +1072,28 @@ Como você pode ver, este hook tem o mesmo comportamento de `result.on_failure(:
|
|
|
1071
1072
|
|
|
1072
1073
|
[⬆️ Voltar para o índice](#índice-)
|
|
1073
1074
|
|
|
1075
|
+
#### Desabilitando o mecanismo "safe"
|
|
1076
|
+
|
|
1077
|
+
O mecanismo "safe" é opinativo: ele converte qualquer exceção não tratada dentro de um caso de uso (ou em qualquer passo de um fluxo) em um resultado de falha com `type: :exception`. Isso é poderoso, mas também pode gerar uma **base de código fragmentada**, onde algumas exceções são tratadas com `rescue` dentro do `call!` e outras só são tratadas mais tarde via `on_exception` / `on_failure(:exception)` — tornando o fluxo de controle difícil de acompanhar.
|
|
1078
|
+
|
|
1079
|
+
Se você prefere uma única convenção explícita para o tratamento de exceções — `rescue` padrão dentro dos seus casos de uso — é possível desabilitar as APIs "safe" por completo:
|
|
1080
|
+
|
|
1081
|
+
```ruby
|
|
1082
|
+
Micro::Case.config do |config|
|
|
1083
|
+
config.disable_safe_features = true
|
|
1084
|
+
end
|
|
1085
|
+
```
|
|
1086
|
+
|
|
1087
|
+
Com isso ativo, os usos abaixo levantarão `Micro::Case::Error::SafeFeaturesDisabled`, garantindo que ninguém na base de código reintroduza o caminho "safe" sem querer:
|
|
1088
|
+
|
|
1089
|
+
- Herdar de `Micro::Case::Safe`
|
|
1090
|
+
- Chamar `Micro::Cases.safe_flow(...)`
|
|
1091
|
+
- Chamar `Micro::Case::Result#on_exception`
|
|
1092
|
+
|
|
1093
|
+
Veja [`Micro::Case.config`](#microcaseconfig) para a lista completa de configurações disponíveis.
|
|
1094
|
+
|
|
1095
|
+
[⬆️ Voltar para o índice](#índice-)
|
|
1096
|
+
|
|
1074
1097
|
### Validando atributos com `accept:` / `reject:`
|
|
1075
1098
|
|
|
1076
1099
|
Desde a versão `5.2.0` do `u-case`, todo caso de uso já inclui a [extensão `accept`](https://github.com/serradura/u-attributes#accept-extension) do [`u-attributes`](https://github.com/serradura/u-attributes) (requer `u-attributes >= 2.8`). Você pode declarar a expectativa de tipo (ou qualquer outra verificação) diretamente no atributo, e o caso de uso falhará automaticamente com o tipo `:invalid_attributes` quando algum atributo for rejeitado — sem precisar validar dentro do `call!`.
|
|
@@ -1226,6 +1249,14 @@ Micro::Case.config do |config|
|
|
|
1226
1249
|
|
|
1227
1250
|
# Use para habilitar/desabilitar o `Micro::Case::Results#transitions`.
|
|
1228
1251
|
config.enable_transitions = true
|
|
1252
|
+
|
|
1253
|
+
# Use para proibir as funcionalidades "safe" e garantir uma única forma de tratar
|
|
1254
|
+
# exceções (via `rescue` padrão). Quando `true`, os itens abaixo levantarão
|
|
1255
|
+
# `Micro::Case::Error::SafeFeaturesDisabled`:
|
|
1256
|
+
# - Herdar de `Micro::Case::Safe`
|
|
1257
|
+
# - Chamar `Micro::Cases.safe_flow(...)`
|
|
1258
|
+
# - Chamar `Micro::Case::Result#on_exception`
|
|
1259
|
+
config.disable_safe_features = false
|
|
1229
1260
|
end
|
|
1230
1261
|
```
|
|
1231
1262
|
|
data/lib/micro/case/config.rb
CHANGED
|
@@ -13,6 +13,16 @@ module Micro
|
|
|
13
13
|
)
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
def disable_safe_features=(value)
|
|
17
|
+
@disable_safe_features = Kind::Boolean[value]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def disable_safe_features
|
|
21
|
+
return @disable_safe_features if defined?(@disable_safe_features)
|
|
22
|
+
|
|
23
|
+
@disable_safe_features = false
|
|
24
|
+
end
|
|
25
|
+
|
|
16
26
|
def enable_activemodel_validation=(value)
|
|
17
27
|
return unless Kind::Boolean[value]
|
|
18
28
|
|
data/lib/micro/case/error.rb
CHANGED
|
@@ -51,6 +51,15 @@ module Micro
|
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
+
class SafeFeaturesDisabled < StandardError
|
|
55
|
+
def initialize(context)
|
|
56
|
+
super(
|
|
57
|
+
"#{context} can't be used because the safe features are disabled. " \
|
|
58
|
+
"To re-enable them, set `config.disable_safe_features = false`."
|
|
59
|
+
)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
54
63
|
def self.by_wrong_usage?(exception)
|
|
55
64
|
case exception
|
|
56
65
|
when Kind::Error, ArgumentError, InvalidResult, UnexpectedResult then true
|
data/lib/micro/case/result.rb
CHANGED
|
@@ -121,6 +121,10 @@ module Micro
|
|
|
121
121
|
end
|
|
122
122
|
|
|
123
123
|
def on_exception(expected_exception = nil)
|
|
124
|
+
if Config.instance.disable_safe_features
|
|
125
|
+
raise Error::SafeFeaturesDisabled.new('Micro::Case::Result#on_exception')
|
|
126
|
+
end
|
|
127
|
+
|
|
124
128
|
return self unless __failure_type?(:exception)
|
|
125
129
|
|
|
126
130
|
if !expected_exception || (Kind.is?(Exception, expected_exception) && data.fetch(:exception).is_a?(expected_exception))
|
data/lib/micro/case/safe.rb
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
module Micro
|
|
4
4
|
class Case
|
|
5
5
|
class Safe < ::Micro::Case
|
|
6
|
+
def self.inherited(subclass)
|
|
7
|
+
if Config.instance.disable_safe_features
|
|
8
|
+
raise Error::SafeFeaturesDisabled.new('Micro::Case::Safe')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
super
|
|
12
|
+
end
|
|
13
|
+
|
|
6
14
|
def self.__flow_builder__
|
|
7
15
|
Cases::Safe::Flow
|
|
8
16
|
end
|
data/lib/micro/case/version.rb
CHANGED
data/lib/micro/case.rb
CHANGED
|
@@ -11,9 +11,9 @@ module Micro
|
|
|
11
11
|
require 'micro/case/utils'
|
|
12
12
|
require 'micro/case/error'
|
|
13
13
|
require 'micro/case/result'
|
|
14
|
+
require 'micro/case/config'
|
|
14
15
|
require 'micro/case/safe'
|
|
15
16
|
require 'micro/case/strict'
|
|
16
|
-
require 'micro/case/config'
|
|
17
17
|
|
|
18
18
|
require 'micro/cases'
|
|
19
19
|
|
data/lib/micro/cases.rb
CHANGED