Skip to content

Commit

Permalink
Merge pull request #11 from KaririCode-Framework/develop
Browse files Browse the repository at this point in the history
feat(processor-pipeline): add processingFailed method to ProcessorRun…
  • Loading branch information
walmir-silva authored Oct 25, 2024
2 parents e43ba4c + 7f49900 commit 0b0229f
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 23 deletions.
21 changes: 15 additions & 6 deletions src/Exception/ProcessorRuntimeException.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ final class ProcessorRuntimeException extends RuntimeException
private const CODE_INVALID_PROCESSOR = 2603;
private const CODE_INVALID_CONTEXT = 2604;
private const CODE_PROCESSOR_CONFIG_INVALID = 2605;
private const ERROR_PREFIX = 'PROCESSOR';
private const CODE_PROCESSING_FAILED = 2606;

public static function contextNotFound(string $context): self
{
return self::createException(
self::CODE_CONTEXT_NOT_FOUND,
self::ERROR_PREFIX . '_CONTEXT_NOT_FOUND',
'PROCESSOR_CONTEXT_NOT_FOUND',
"Processor context '{$context}' not found"
);
}
Expand All @@ -28,7 +28,7 @@ public static function processorNotFound(string $processorName, string $context)
{
return self::createException(
self::CODE_PROCESSOR_NOT_FOUND,
self::ERROR_PREFIX . '_NOT_FOUND',
'PROCESSOR_NOT_FOUND',
"Processor '{$processorName}' not found in context '{$context}'"
);
}
Expand All @@ -37,7 +37,7 @@ public static function invalidProcessor(string $processorName, string $details):
{
return self::createException(
self::CODE_INVALID_PROCESSOR,
self::ERROR_PREFIX . '_INVALID',
'PROCESSOR_INVALID',
"Invalid processor '{$processorName}': {$details}"
);
}
Expand All @@ -46,7 +46,7 @@ public static function invalidContext(string $context, string $details): self
{
return self::createException(
self::CODE_INVALID_CONTEXT,
self::ERROR_PREFIX . '_CONTEXT_INVALID',
'PROCESSOR_CONTEXT_INVALID',
"Invalid processor context '{$context}': {$details}"
);
}
Expand All @@ -55,8 +55,17 @@ public static function invalidConfiguration(string $processorName, string $detai
{
return self::createException(
self::CODE_PROCESSOR_CONFIG_INVALID,
self::ERROR_PREFIX . '_CONFIG_INVALID',
'PROCESSOR_CONFIG_INVALID',
"Invalid processor configuration for '{$processorName}': {$details}"
);
}

public static function processingFailed(string $property): self
{
return self::createException(
self::CODE_PROCESSING_FAILED,
'PROCESSOR_PROCESSING_FAILED',
"Processing failed for property '{$property}'",
);
}
}
8 changes: 8 additions & 0 deletions src/Handler/AttributeHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,12 @@ public function getProcessingResultMessages(): array
{
return $this->processingResultMessages;
}

public function reset(): void
{
$this->processedPropertyValues = [];
$this->processingResultErrors = [];
$this->processingResultMessages = [];
$this->processorCache = [];
}
}
103 changes: 86 additions & 17 deletions src/Handler/ProcessorAttributeHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,63 @@
namespace KaririCode\ProcessorPipeline\Handler;

use KaririCode\Contract\Processor\ProcessorBuilder;
use KaririCode\ProcessorPipeline\AttributeHandler;
use KaririCode\Contract\Processor\ValidatableProcessor;
use KaririCode\ProcessorPipeline\Exception\ProcessorRuntimeException;
use KaririCode\ProcessorPipeline\Processor\ProcessorConfigBuilder;
use KaririCode\ProcessorPipeline\Processor\ProcessorValidator;
use KaririCode\ProcessorPipeline\Result\ProcessingResultCollection;

/**
* Handler for processing attributes with configured processors.
*/
final class ProcessorAttributeHandler extends AttributeHandler
{
private ProcessingResultCollection $results;

public function __construct(
string $identifier,
ProcessorBuilder $builder
private readonly string $identifier,
private readonly ProcessorBuilder $builder,
private readonly ProcessorValidator $validator = new ProcessorValidator(),
private readonly ProcessorConfigBuilder $configBuilder = new ProcessorConfigBuilder()
) {
parent::__construct($identifier, $builder);
$this->results = new ProcessingResultCollection();
}

public function processPropertyValue(string $property, mixed $value): mixed
public function handleAttribute(string $propertyName, object $attribute, mixed $value): mixed
{
$processorSpecs = $this->getPropertyProcessors($property);
$result = parent::handleAttribute($propertyName, $attribute, $value);

if (empty($processorSpecs)) {
return $value;
if (null !== $result) {
$this->transferResults($propertyName);
}

try {
$pipeline = $this->builder->buildPipeline(
$this->identifier,
$processorSpecs
);
return $result;
}

$processedValue = $pipeline->process($value);
$this->results->setProcessedData($property, $processedValue);
/**
* Transfers results from parent handler to ProcessingResultCollection.
*/
private function transferResults(string $propertyName): void
{
$processedValues = parent::getProcessedPropertyValues();
$errors = parent::getProcessingResultErrors();

return $processedValue;
} catch (\Exception $e) {
throw ProcessorRuntimeException::processingFailed($property, $e);
if (isset($processedValues[$propertyName])) {
$this->results->setProcessedData(
$propertyName,
$processedValues[$propertyName]['value']
);
}

if (isset($errors[$propertyName])) {
foreach ($errors[$propertyName] as $processorName => $error) {
$this->results->addError(
$propertyName,
$error['errorKey'] ?? 'processing_error',
$error['message'] ?? 'Unknown error'
);
}
}
}

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

/**
* Checks if there are any processing errors.
*/
public function hasErrors(): bool
{
return $this->results->hasErrors();
}

/**
* Gets the processing results collection.
*/
public function getProcessingResults(): ProcessingResultCollection
{
return $this->results;
}

/**
* Resets the processing state.
*/
public function reset(): void
{
parent::reset();
$this->results = new ProcessingResultCollection();
}

protected function validateProcessors(array $processorsConfig, array $messages): array
{
$errors = [];

foreach ($processorsConfig as $processorName => $config) {
$processor = $this->builder->build(
$this->identifier,
$processorName,
$config
);

if ($processor instanceof ValidatableProcessor && !$processor->isValid()) {
$errorKey = $processor->getErrorKey();
$message = $messages[$processorName] ?? "Validation failed for $processorName";

$errors[$processorName] = [
'errorKey' => $errorKey,
'message' => $message,
];

$this->results->addError($processorName, $errorKey, $message);
}
}

return $errors;
}

protected function processValue(mixed $value, array $config): mixed
{
try {
return $this->builder
->buildPipeline($this->identifier, $config)
->process($value);
} catch (\Exception $e) {
throw ProcessorRuntimeException::processingFailed($value);
}
}
}

0 comments on commit 0b0229f

Please sign in to comment.