From dbdb8ef37232e4cfa45dc80b96a0e3f059efde9c Mon Sep 17 00:00:00 2001 From: Yevhen Sidelnyk Date: Wed, 18 Mar 2026 09:21:50 +0200 Subject: [PATCH 1/2] refactor: move `message` argument of `#[Catch_]` attribute to be after `format` --- README.md | 8 ++++---- UPGRADE.md | 9 +++++++++ .../Rule/Object/Property/Catch_.php | 12 ++++++------ .../PropertyMatchingRulesAssembler.php | 2 +- .../Closure/Tests/Stub/ConditionalMessage.php | 4 ++-- .../Property/Match/MatchExceptionRule.php | 12 ++++++------ tests/Unit/Stub/HandleableMessageStub.php | 18 +++++++++--------- tests/Unit/Stub/NestedHandleableMessage.php | 2 +- tests/Unit/Stub/NestedItem.php | 2 +- tests/Unit/Stub/NotHandleableMessageStub.php | 2 +- 10 files changed, 40 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 2d30e7d..63e7e9b 100644 --- a/README.md +++ b/README.md @@ -127,10 +127,10 @@ use PhPhD\ExceptionalMatcher\Rule\Object\Property\Catch_; #[Try_] class RegisterUserCommand { - #[Catch_(LoginAlreadyTakenException::class, 'auth.login.already_taken')] + #[Catch_(LoginAlreadyTakenException::class, message: 'auth.login.already_taken')] public string $login; - #[Catch_(WeakPasswordException::class, 'auth.password.weak')] + #[Catch_(WeakPasswordException::class, message: 'auth.password.weak')] public string $password; } ``` @@ -181,11 +181,11 @@ A comparison of the approaches would look something like this: class RegisterUserCommand { - #[App\Assert\UniqueLogin] -+ #[Catch_(LoginAlreadyTakenException::class, 'auth.login.already_taken')] ++ #[Catch_(LoginAlreadyTakenException::class, message: 'auth.login.already_taken')] public string $login; - #[Assert\PasswordStrength(minScore: 2)] -+ #[Catch_(WeakPasswordException::class, 'auth.password.weak')] ++ #[Catch_(WeakPasswordException::class, message: 'auth.password.weak')] public string $password; } ``` diff --git a/UPGRADE.md b/UPGRADE.md index e7d217b..c8e14d6 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -23,3 +23,12 @@ for the changes not covered by automatic upgrade via Rector (see the "Upgrading" * Renamed: `PhPhD\ExceptionalMatcher\Rule\Object\Property\Catch_::$formatter` \ was renamed into `$format`. + +* Parameter Moved: `PhPhD\ExceptionalMatcher\Rule\Object\Property\Catch_::$message` \ + was moved to be after `$format`. + + Not moving it will cause this error: + > Parameter #2 `$from` of attribute class `PhPhD\ExceptionalMatcher\Rule\Object\Property\Catch_` constructor expects `array{class-string, non-empty-string}|class-string|null`, + > `'exception.message'` given. + + Fix it by passing it as a named parameter: `message: 'exception.message'`. diff --git a/src/ExceptionalMatcher/Rule/Object/Property/Catch_.php b/src/ExceptionalMatcher/Rule/Object/Property/Catch_.php index 27da805..8f7cebe 100644 --- a/src/ExceptionalMatcher/Rule/Object/Property/Catch_.php +++ b/src/ExceptionalMatcher/Rule/Object/Property/Catch_.php @@ -33,7 +33,6 @@ final class Catch_ public function __construct( /** @var class-string */ private readonly string $exception, - private readonly ?string $message = null, /** @var null|class-string|array{class-string,non-empty-string} The origin of the exception */ private readonly array|string|null $from = null, /** @note match condition class is contravariant to the exception */ @@ -42,6 +41,7 @@ public function __construct( private readonly ?array $if = null, /** @note formatter class is contravariant to the exception */ private readonly string $format = MainExceptionViolationFormatter::class, // @phpstan-ignore phpat.testModelDependencies (really, this's a fair catch - it should not depend on the formatter) + private readonly ?string $message = null, ) { if (null !== $this->if) { Assert::count($this->if, 2); @@ -58,11 +58,6 @@ public function getExceptionClass(): string return $this->exception; } - public function getMessage(): ?string - { - return $this->message; - } - /** @return ?array{class-string,?non-empty-string} */ public function getFrom(): ?array { @@ -98,4 +93,9 @@ public function getFormat(): string { return $this->format; } + + public function getMessage(): ?string + { + return $this->message; + } } diff --git a/src/ExceptionalMatcher/Rule/Object/Property/Match/Assembler/PropertyMatchingRulesAssembler.php b/src/ExceptionalMatcher/Rule/Object/Property/Match/Assembler/PropertyMatchingRulesAssembler.php index 5d593e2..7d24342 100644 --- a/src/ExceptionalMatcher/Rule/Object/Property/Match/Assembler/PropertyMatchingRulesAssembler.php +++ b/src/ExceptionalMatcher/Rule/Object/Property/Match/Assembler/PropertyMatchingRulesAssembler.php @@ -39,8 +39,8 @@ public function assembleRules(MatchConditionFactory $matchConditionFactory): ?Co $rules->append(new MatchExceptionRule( $ruleSet, $condition, - $catchAttribute->getMessage(), $catchAttribute->getFormat(), + $catchAttribute->getMessage(), )); } diff --git a/src/ExceptionalMatcher/Rule/Object/Property/Match/Condition/Closure/Tests/Stub/ConditionalMessage.php b/src/ExceptionalMatcher/Rule/Object/Property/Match/Condition/Closure/Tests/Stub/ConditionalMessage.php index c8bf690..31c4f6a 100644 --- a/src/ExceptionalMatcher/Rule/Object/Property/Match/Condition/Closure/Tests/Stub/ConditionalMessage.php +++ b/src/ExceptionalMatcher/Rule/Object/Property/Match/Condition/Closure/Tests/Stub/ConditionalMessage.php @@ -10,10 +10,10 @@ #[Try_] final class ConditionalMessage { - #[Catch_(ConditionallyCaughtException::class, 'oops', if: [self::class, 'firstPropertyMatchesException'])] + #[Catch_(ConditionallyCaughtException::class, if: [self::class, 'firstPropertyMatchesException'], message: 'oops')] private int $firstProperty; - #[Catch_(ConditionallyCaughtException::class, 'oops', if: [self::class, 'secondPropertyMatchesException'])] + #[Catch_(ConditionallyCaughtException::class, if: [self::class, 'secondPropertyMatchesException'], message: 'oops')] private int $secondProperty; public static function createWithConditionalProperties(int $firstConditionalProperty, int $secondConditionalProperty): self diff --git a/src/ExceptionalMatcher/Rule/Object/Property/Match/MatchExceptionRule.php b/src/ExceptionalMatcher/Rule/Object/Property/Match/MatchExceptionRule.php index fdba22b..0f5529b 100644 --- a/src/ExceptionalMatcher/Rule/Object/Property/Match/MatchExceptionRule.php +++ b/src/ExceptionalMatcher/Rule/Object/Property/Match/MatchExceptionRule.php @@ -22,9 +22,9 @@ public function __construct( private readonly MatchingRule $parent, /** @var MatchCondition */ private readonly MatchCondition $condition, - private readonly ?string $messageTemplate, /** @var class-string> */ private readonly string $formatterId, + private readonly ?string $messageTemplate, ) { } @@ -66,14 +66,14 @@ public function matchesException(Throwable $exception): bool return $this->condition->matches($exception); } - public function getMessageTemplate(): ?string - { - return $this->messageTemplate; - } - /** @return class-string> */ public function getFormatterId(): string { return $this->formatterId; } + + public function getMessageTemplate(): ?string + { + return $this->messageTemplate; + } } diff --git a/tests/Unit/Stub/HandleableMessageStub.php b/tests/Unit/Stub/HandleableMessageStub.php index 8018c98..16ebde7 100644 --- a/tests/Unit/Stub/HandleableMessageStub.php +++ b/tests/Unit/Stub/HandleableMessageStub.php @@ -27,16 +27,16 @@ #[Try_] final class HandleableMessageStub { - #[Catch_(AnException::class, 'oops')] + #[Catch_(AnException::class, message: 'oops')] private int $property; - #[Catch_(CustomFormattedException::class, 'oops', format: CustomExceptionViolationFormatter::class)] + #[Catch_(CustomFormattedException::class, format: CustomExceptionViolationFormatter::class, message: 'oops')] private string $formatted; - #[Catch_(ObjectPropertyMatchedException::class, 'oops')] + #[Catch_(ObjectPropertyMatchedException::class, message: 'oops')] private object $objectProperty; - #[Catch_(StaticPropertyMatchedException::class, 'oops')] + #[Catch_(StaticPropertyMatchedException::class, message: 'oops')] private static string $staticProperty = 'foo'; private NestedHandleableMessage $nestedObject; @@ -51,24 +51,24 @@ final class HandleableMessageStub #[Catch_(InvalidArgumentException::class, from: [Uuid::class, 'fromString'])] private string $uid; - #[Catch_(LogicException::class, 'oops')] + #[Catch_(LogicException::class, message: 'oops')] private string $messageText; - #[Catch_(SomeValueException::class, 'oops', match: ExceptionValueMatchCondition::class)] + #[Catch_(SomeValueException::class, match: ExceptionValueMatchCondition::class, message: 'oops')] #[Catch_(ValidationFailedException::class, match: ValidationFailedExceptionMatchCondition::class, format: ValidationFailedExceptionFormatter::class)] private string $notMatchedProperty = 'not matched'; - #[Catch_(SomeValueException::class, 'oops', match: ExceptionValueMatchCondition::class)] + #[Catch_(SomeValueException::class, match: ExceptionValueMatchCondition::class, message: 'oops')] #[Catch_(ValidationFailedException::class, match: ValidationFailedExceptionMatchCondition::class, format: ValidationFailedExceptionFormatter::class)] private string $matchedProperty = 'matched!'; - #[Catch_(SomeValueException::class, 'oops')] + #[Catch_(SomeValueException::class, message: 'oops')] private string $anotherMatchedAsNoCondition; #[Catch_(MessageContainingException::class)] private int $fallBackToExceptionMessage; - #[Catch_(MessageContainingException::class, '')] + #[Catch_(MessageContainingException::class, message: '')] private string $emptyTranslationMessage; private function __construct() diff --git a/tests/Unit/Stub/NestedHandleableMessage.php b/tests/Unit/Stub/NestedHandleableMessage.php index 451fb21..93b74a9 100644 --- a/tests/Unit/Stub/NestedHandleableMessage.php +++ b/tests/Unit/Stub/NestedHandleableMessage.php @@ -15,7 +15,7 @@ #[Try_] final class NestedHandleableMessage { - #[Catch_(NestedPropertyMatchedException::class, 'nested.message')] + #[Catch_(NestedPropertyMatchedException::class, message: 'nested.message')] private string $nestedProperty; #[Valid] diff --git a/tests/Unit/Stub/NestedItem.php b/tests/Unit/Stub/NestedItem.php index e364718..aca77e7 100644 --- a/tests/Unit/Stub/NestedItem.php +++ b/tests/Unit/Stub/NestedItem.php @@ -12,7 +12,7 @@ final class NestedItem { public function __construct( - #[Catch_(NestedItemMatchedException::class, 'oops', if: [self::class, 'matchesValue'])] + #[Catch_(NestedItemMatchedException::class, if: [self::class, 'matchesValue'], message: 'oops')] private readonly int $property, ) { } diff --git a/tests/Unit/Stub/NotHandleableMessageStub.php b/tests/Unit/Stub/NotHandleableMessageStub.php index 3eacf1b..6a0b95f 100644 --- a/tests/Unit/Stub/NotHandleableMessageStub.php +++ b/tests/Unit/Stub/NotHandleableMessageStub.php @@ -12,7 +12,7 @@ final class NotHandleableMessageStub { public function __construct( - #[Catch_(AnException::class, 'not matched')] + #[Catch_(AnException::class, message: 'not matched')] private readonly int $property, ) { } From 3123735b4d18cfe1256d9324680bf8dbbeeda75f Mon Sep 17 00:00:00 2001 From: Yevhen Sidelnyk Date: Wed, 18 Mar 2026 09:32:15 +0200 Subject: [PATCH 2/2] refactor: remove unused `Valid` reference from `ArchitectureRuleSet` --- tests/ArchitectureRuleSet.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/ArchitectureRuleSet.php b/tests/ArchitectureRuleSet.php index 07e171c..a984b11 100644 --- a/tests/ArchitectureRuleSet.php +++ b/tests/ArchitectureRuleSet.php @@ -20,7 +20,6 @@ use PHPUnit\Framework\TestCase; use Psr\Container\ContainerInterface; use Symfony\Component\Uid\Exception\InvalidArgumentException as InvalidUidException; -use Symfony\Component\Validator\Constraints\Valid; use Symfony\Component\Validator\ConstraintViolationListInterface; use Symfony\Component\Validator\Exception\ValidationFailedException; use Symfony\Contracts\Translation\TranslatorInterface; @@ -131,7 +130,6 @@ public function layers(): array 'deps' => [ $this->model(), $this->matchCondition(), - Selector::classname(Valid::class), Selector::classname(Assert::class), ], ],