Skip to content

Commit 0b0229f

Browse files
authored
Merge pull request #11 from KaririCode-Framework/develop
feat(processor-pipeline): add processingFailed method to ProcessorRun…
2 parents e43ba4c + 7f49900 commit 0b0229f

File tree

3 files changed

+109
-23
lines changed

3 files changed

+109
-23
lines changed

src/Exception/ProcessorRuntimeException.php

+15-6
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ final class ProcessorRuntimeException extends RuntimeException
1313
private const CODE_INVALID_PROCESSOR = 2603;
1414
private const CODE_INVALID_CONTEXT = 2604;
1515
private const CODE_PROCESSOR_CONFIG_INVALID = 2605;
16-
private const ERROR_PREFIX = 'PROCESSOR';
16+
private const CODE_PROCESSING_FAILED = 2606;
1717

1818
public static function contextNotFound(string $context): self
1919
{
2020
return self::createException(
2121
self::CODE_CONTEXT_NOT_FOUND,
22-
self::ERROR_PREFIX . '_CONTEXT_NOT_FOUND',
22+
'PROCESSOR_CONTEXT_NOT_FOUND',
2323
"Processor context '{$context}' not found"
2424
);
2525
}
@@ -28,7 +28,7 @@ public static function processorNotFound(string $processorName, string $context)
2828
{
2929
return self::createException(
3030
self::CODE_PROCESSOR_NOT_FOUND,
31-
self::ERROR_PREFIX . '_NOT_FOUND',
31+
'PROCESSOR_NOT_FOUND',
3232
"Processor '{$processorName}' not found in context '{$context}'"
3333
);
3434
}
@@ -37,7 +37,7 @@ public static function invalidProcessor(string $processorName, string $details):
3737
{
3838
return self::createException(
3939
self::CODE_INVALID_PROCESSOR,
40-
self::ERROR_PREFIX . '_INVALID',
40+
'PROCESSOR_INVALID',
4141
"Invalid processor '{$processorName}': {$details}"
4242
);
4343
}
@@ -46,7 +46,7 @@ public static function invalidContext(string $context, string $details): self
4646
{
4747
return self::createException(
4848
self::CODE_INVALID_CONTEXT,
49-
self::ERROR_PREFIX . '_CONTEXT_INVALID',
49+
'PROCESSOR_CONTEXT_INVALID',
5050
"Invalid processor context '{$context}': {$details}"
5151
);
5252
}
@@ -55,8 +55,17 @@ public static function invalidConfiguration(string $processorName, string $detai
5555
{
5656
return self::createException(
5757
self::CODE_PROCESSOR_CONFIG_INVALID,
58-
self::ERROR_PREFIX . '_CONFIG_INVALID',
58+
'PROCESSOR_CONFIG_INVALID',
5959
"Invalid processor configuration for '{$processorName}': {$details}"
6060
);
6161
}
62+
63+
public static function processingFailed(string $property): self
64+
{
65+
return self::createException(
66+
self::CODE_PROCESSING_FAILED,
67+
'PROCESSOR_PROCESSING_FAILED',
68+
"Processing failed for property '{$property}'",
69+
);
70+
}
6271
}

src/Handler/AttributeHandler.php

+8
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,12 @@ public function getProcessingResultMessages(): array
126126
{
127127
return $this->processingResultMessages;
128128
}
129+
130+
public function reset(): void
131+
{
132+
$this->processedPropertyValues = [];
133+
$this->processingResultErrors = [];
134+
$this->processingResultMessages = [];
135+
$this->processorCache = [];
136+
}
129137
}

src/Handler/ProcessorAttributeHandler.php

+86-17
Original file line numberDiff line numberDiff line change
@@ -5,42 +5,63 @@
55
namespace KaririCode\ProcessorPipeline\Handler;
66

77
use KaririCode\Contract\Processor\ProcessorBuilder;
8-
use KaririCode\ProcessorPipeline\AttributeHandler;
8+
use KaririCode\Contract\Processor\ValidatableProcessor;
99
use KaririCode\ProcessorPipeline\Exception\ProcessorRuntimeException;
10+
use KaririCode\ProcessorPipeline\Processor\ProcessorConfigBuilder;
11+
use KaririCode\ProcessorPipeline\Processor\ProcessorValidator;
1012
use KaririCode\ProcessorPipeline\Result\ProcessingResultCollection;
1113

14+
/**
15+
* Handler for processing attributes with configured processors.
16+
*/
1217
final class ProcessorAttributeHandler extends AttributeHandler
1318
{
1419
private ProcessingResultCollection $results;
1520

1621
public function __construct(
17-
string $identifier,
18-
ProcessorBuilder $builder
22+
private readonly string $identifier,
23+
private readonly ProcessorBuilder $builder,
24+
private readonly ProcessorValidator $validator = new ProcessorValidator(),
25+
private readonly ProcessorConfigBuilder $configBuilder = new ProcessorConfigBuilder()
1926
) {
2027
parent::__construct($identifier, $builder);
2128
$this->results = new ProcessingResultCollection();
2229
}
2330

24-
public function processPropertyValue(string $property, mixed $value): mixed
31+
public function handleAttribute(string $propertyName, object $attribute, mixed $value): mixed
2532
{
26-
$processorSpecs = $this->getPropertyProcessors($property);
33+
$result = parent::handleAttribute($propertyName, $attribute, $value);
2734

28-
if (empty($processorSpecs)) {
29-
return $value;
35+
if (null !== $result) {
36+
$this->transferResults($propertyName);
3037
}
3138

32-
try {
33-
$pipeline = $this->builder->buildPipeline(
34-
$this->identifier,
35-
$processorSpecs
36-
);
39+
return $result;
40+
}
3741

38-
$processedValue = $pipeline->process($value);
39-
$this->results->setProcessedData($property, $processedValue);
42+
/**
43+
* Transfers results from parent handler to ProcessingResultCollection.
44+
*/
45+
private function transferResults(string $propertyName): void
46+
{
47+
$processedValues = parent::getProcessedPropertyValues();
48+
$errors = parent::getProcessingResultErrors();
4049

41-
return $processedValue;
42-
} catch (\Exception $e) {
43-
throw ProcessorRuntimeException::processingFailed($property, $e);
50+
if (isset($processedValues[$propertyName])) {
51+
$this->results->setProcessedData(
52+
$propertyName,
53+
$processedValues[$propertyName]['value']
54+
);
55+
}
56+
57+
if (isset($errors[$propertyName])) {
58+
foreach ($errors[$propertyName] as $processorName => $error) {
59+
$this->results->addError(
60+
$propertyName,
61+
$error['errorKey'] ?? 'processing_error',
62+
$error['message'] ?? 'Unknown error'
63+
);
64+
}
4465
}
4566
}
4667

@@ -57,18 +78,66 @@ public function getProcessingResultErrors(): array
5778
return $this->results->getErrors();
5879
}
5980

81+
/**
82+
* Checks if there are any processing errors.
83+
*/
6084
public function hasErrors(): bool
6185
{
6286
return $this->results->hasErrors();
6387
}
6488

89+
/**
90+
* Gets the processing results collection.
91+
*/
6592
public function getProcessingResults(): ProcessingResultCollection
6693
{
6794
return $this->results;
6895
}
6996

97+
/**
98+
* Resets the processing state.
99+
*/
70100
public function reset(): void
71101
{
102+
parent::reset();
72103
$this->results = new ProcessingResultCollection();
73104
}
105+
106+
protected function validateProcessors(array $processorsConfig, array $messages): array
107+
{
108+
$errors = [];
109+
110+
foreach ($processorsConfig as $processorName => $config) {
111+
$processor = $this->builder->build(
112+
$this->identifier,
113+
$processorName,
114+
$config
115+
);
116+
117+
if ($processor instanceof ValidatableProcessor && !$processor->isValid()) {
118+
$errorKey = $processor->getErrorKey();
119+
$message = $messages[$processorName] ?? "Validation failed for $processorName";
120+
121+
$errors[$processorName] = [
122+
'errorKey' => $errorKey,
123+
'message' => $message,
124+
];
125+
126+
$this->results->addError($processorName, $errorKey, $message);
127+
}
128+
}
129+
130+
return $errors;
131+
}
132+
133+
protected function processValue(mixed $value, array $config): mixed
134+
{
135+
try {
136+
return $this->builder
137+
->buildPipeline($this->identifier, $config)
138+
->process($value);
139+
} catch (\Exception $e) {
140+
throw ProcessorRuntimeException::processingFailed($value);
141+
}
142+
}
74143
}

0 commit comments

Comments
 (0)