Skip to content

Commit cb916d9

Browse files
authored
Merge pull request #9 from KaririCode-Framework/develop
commit: feat(processor-pipeline): add domain-specific exception handling
2 parents 58a25f3 + 3ac964d commit cb916d9

12 files changed

+579
-56
lines changed

composer.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
"require": {
2323
"php": "^8.3",
2424
"kariricode/data-structure": "^1.1",
25-
"kariricode/contract": "^2.7"
25+
"kariricode/contract": "^2.7",
26+
"kariricode/property-inspector": "^1.0",
27+
"kariricode/exception": "^1.2"
2628
},
2729
"autoload": {
2830
"psr-4": {

composer.lock

+125-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Exception/ProcessingException.php

+25-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,30 @@
44

55
namespace KaririCode\ProcessorPipeline\Exception;
66

7-
final class ProcessingException extends \RuntimeException
7+
use KaririCode\Exception\AbstractException;
8+
9+
final class ProcessingException extends AbstractException
810
{
11+
private const CODE_PIPELINE_FAILED = 3001;
12+
private const CODE_PROCESSOR_FAILED = 3002;
13+
14+
public static function pipelineExecutionFailed(): self
15+
{
16+
return self::createException(
17+
self::CODE_PIPELINE_FAILED,
18+
'PIPELINE_FAILED',
19+
'Pipeline processing failed'
20+
);
21+
}
22+
23+
public static function processorExecutionFailed(string $processorClass): self
24+
{
25+
$message = sprintf('Processor %s execution failed', $processorClass);
26+
27+
return self::createException(
28+
self::CODE_PROCESSOR_FAILED,
29+
'PROCESSOR_FAILED',
30+
$message
31+
);
32+
}
933
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KaririCode\ProcessorPipeline\Exception;
6+
7+
use KaririCode\Exception\Runtime\RuntimeException;
8+
9+
final class ProcessorRuntimeException extends RuntimeException
10+
{
11+
private const CODE_CONTEXT_NOT_FOUND = 2601;
12+
private const CODE_PROCESSOR_NOT_FOUND = 2602;
13+
private const CODE_INVALID_PROCESSOR = 2603;
14+
private const CODE_INVALID_CONTEXT = 2604;
15+
private const CODE_PROCESSOR_CONFIG_INVALID = 2605;
16+
private const ERROR_PREFIX = 'PROCESSOR';
17+
18+
public static function contextNotFound(string $context): self
19+
{
20+
return self::createException(
21+
self::CODE_CONTEXT_NOT_FOUND,
22+
self::ERROR_PREFIX . '_CONTEXT_NOT_FOUND',
23+
"Processor context '{$context}' not found"
24+
);
25+
}
26+
27+
public static function processorNotFound(string $processorName, string $context): self
28+
{
29+
return self::createException(
30+
self::CODE_PROCESSOR_NOT_FOUND,
31+
self::ERROR_PREFIX . '_NOT_FOUND',
32+
"Processor '{$processorName}' not found in context '{$context}'"
33+
);
34+
}
35+
36+
public static function invalidProcessor(string $processorName, string $details): self
37+
{
38+
return self::createException(
39+
self::CODE_INVALID_PROCESSOR,
40+
self::ERROR_PREFIX . '_INVALID',
41+
"Invalid processor '{$processorName}': {$details}"
42+
);
43+
}
44+
45+
public static function invalidContext(string $context, string $details): self
46+
{
47+
return self::createException(
48+
self::CODE_INVALID_CONTEXT,
49+
self::ERROR_PREFIX . '_CONTEXT_INVALID',
50+
"Invalid processor context '{$context}': {$details}"
51+
);
52+
}
53+
54+
public static function invalidConfiguration(string $processorName, string $details): self
55+
{
56+
return self::createException(
57+
self::CODE_PROCESSOR_CONFIG_INVALID,
58+
self::ERROR_PREFIX . '_CONFIG_INVALID',
59+
"Invalid processor configuration for '{$processorName}': {$details}"
60+
);
61+
}
62+
}
+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace KaririCode\ProcessorPipeline\Handler;
6+
7+
use KaririCode\Contract\Processor\ProcessorBuilder;
8+
use KaririCode\Contract\Processor\ValidatableProcessor;
9+
use KaririCode\ProcessorPipeline\Result\ProcessedData;
10+
use KaririCode\ProcessorPipeline\Result\ProcessingError;
11+
use KaririCode\ProcessorPipeline\Result\ProcessingResultCollection;
12+
use KaririCode\PropertyInspector\AttributeHandler;
13+
14+
class ProcessorAttributeHandler extends AttributeHandler
15+
{
16+
protected ProcessingResultCollection $results;
17+
18+
public function __construct(
19+
private readonly string $identifier,
20+
private readonly ProcessorBuilder $builder
21+
) {
22+
parent::__construct($identifier, $builder);
23+
$this->results = new ProcessingResultCollection();
24+
}
25+
26+
public function processPropertyValue(string $property, mixed $value): mixed
27+
{
28+
$pipeline = $this->builder->buildPipeline(
29+
$this->identifier,
30+
$this->getPropertyProcessors($property)
31+
);
32+
33+
try {
34+
$processedValue = $pipeline->process($value);
35+
$this->storeProcessedValue($property, $processedValue);
36+
37+
// Verifica se há erros de validação
38+
$this->checkValidationErrors($property, $pipeline);
39+
40+
return $processedValue;
41+
} catch (\Exception $e) {
42+
$this->storeProcessingError($property, $e);
43+
44+
return $value;
45+
}
46+
}
47+
48+
protected function checkValidationErrors(string $property, $pipeline): void
49+
{
50+
foreach ($pipeline->getProcessors() as $processor) {
51+
if ($processor instanceof ValidatableProcessor && !$processor->isValid()) {
52+
$this->storeValidationError(
53+
$property,
54+
$processor->getErrorKey(),
55+
$processor->getErrorMessage()
56+
);
57+
}
58+
}
59+
}
60+
61+
protected function storeProcessedValue(string $property, mixed $value): void
62+
{
63+
$processedData = new ProcessedData($property, $value);
64+
$this->results->addProcessedData($processedData);
65+
}
66+
67+
protected function storeProcessingError(string $property, \Exception $exception): void
68+
{
69+
$error = new ProcessingError(
70+
$property,
71+
'processingError',
72+
$exception->getMessage()
73+
);
74+
$this->results->addError($error);
75+
}
76+
77+
protected function storeValidationError(string $property, string $errorKey, string $message): void
78+
{
79+
$error = new ProcessingError($property, $errorKey, $message);
80+
$this->results->addError($error);
81+
}
82+
83+
public function getProcessingResults(): ProcessingResultCollection
84+
{
85+
return $this->results;
86+
}
87+
88+
public function getProcessedPropertyValues(): array
89+
{
90+
return $this->results->getProcessedDataAsArray();
91+
}
92+
93+
public function getProcessingResultErrors(): array
94+
{
95+
return $this->results->getErrorsAsArray();
96+
}
97+
98+
public function reset(): void
99+
{
100+
$this->results = new ProcessingResultCollection();
101+
}
102+
}

src/ProcessorBuilder.php

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace KaririCode\ProcessorPipeline;
46

57
use KaririCode\Contract\Processor\ConfigurableProcessor;
@@ -24,9 +26,6 @@ public function build(string $context, string $name, array $processorConfig = []
2426
return $processor;
2527
}
2628

27-
/**
28-
* @param array<string, mixed> $processorSpecs
29-
*/
3029
public function buildPipeline(string $context, array $processorSpecs): Pipeline
3130
{
3231
$pipeline = new ProcessorPipeline();

0 commit comments

Comments
 (0)