diff --git a/src/Metadata/Resource/Factory/OperationDefaultsTrait.php b/src/Metadata/Resource/Factory/OperationDefaultsTrait.php index 93f90ca03a..82d0535e23 100644 --- a/src/Metadata/Resource/Factory/OperationDefaultsTrait.php +++ b/src/Metadata/Resource/Factory/OperationDefaultsTrait.php @@ -225,6 +225,17 @@ private function getOperationWithDefaults(ApiResource $resource, Operation $oper $operationName = $operation->getName() ?? $this->getDefaultOperationName($operation, $resource->getClass()); + $status = $operation->getStatus(); + if (null !== $status && ($status < 100 || $status >= 600)) { + throw new RuntimeException(\sprintf('The HTTP status code "%s" of operation "%s" of resource "%s" is not valid.', $status, $operationName, $resource->getClass())); + } + + foreach ($operation->getExceptionToStatus() ?? [] as $exceptionStatus) { + if (!\is_int($exceptionStatus) || $exceptionStatus < 100 || $exceptionStatus >= 600) { + throw new RuntimeException(\sprintf('The HTTP status code "%s" of operation "%s" of resource "%s" is not valid.', $exceptionStatus, $operationName, $resource->getClass())); + } + } + return [ $operationName, $operation, diff --git a/src/Metadata/Tests/Fixtures/ApiResource/InvalidExceptionToStatusOperation.php b/src/Metadata/Tests/Fixtures/ApiResource/InvalidExceptionToStatusOperation.php new file mode 100644 index 0000000000..c0e3217330 --- /dev/null +++ b/src/Metadata/Tests/Fixtures/ApiResource/InvalidExceptionToStatusOperation.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Metadata\Tests\Fixtures\ApiResource; + +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Get; + +#[ApiResource(operations: [new Get(exceptionToStatus: [\LogicException::class => 999])])] +class InvalidExceptionToStatusOperation +{ + public ?int $id = null; +} diff --git a/src/Metadata/Tests/Resource/Factory/AttributesResourceMetadataCollectionFactoryTest.php b/src/Metadata/Tests/Resource/Factory/AttributesResourceMetadataCollectionFactoryTest.php index 1a995b3736..be5a6a7746 100644 --- a/src/Metadata/Tests/Resource/Factory/AttributesResourceMetadataCollectionFactoryTest.php +++ b/src/Metadata/Tests/Resource/Factory/AttributesResourceMetadataCollectionFactoryTest.php @@ -15,6 +15,7 @@ use ApiPlatform\Metadata\ApiResource; use ApiPlatform\Metadata\Delete; +use ApiPlatform\Metadata\Exception\RuntimeException; use ApiPlatform\Metadata\Get; use ApiPlatform\Metadata\GetCollection; use ApiPlatform\Metadata\GraphQl\DeleteMutation; @@ -37,6 +38,7 @@ use ApiPlatform\Metadata\Tests\Fixtures\ApiResource\AttributeResource; use ApiPlatform\Metadata\Tests\Fixtures\ApiResource\AttributeResources; use ApiPlatform\Metadata\Tests\Fixtures\ApiResource\ExtraPropertiesResource; +use ApiPlatform\Metadata\Tests\Fixtures\ApiResource\InvalidExceptionToStatusOperation; use ApiPlatform\Metadata\Tests\Fixtures\ApiResource\MutationDescription; use ApiPlatform\Metadata\Tests\Fixtures\ApiResource\PasswordResource; use ApiPlatform\Metadata\Tests\Fixtures\ApiResource\ResourceClassPropagation; @@ -379,6 +381,16 @@ public function testDeduplicateShortNames(): void } } + public function testInvalidExceptionToStatusThrows(): void + { + $factory = new AttributesResourceMetadataCollectionFactory(); + + $this->expectException(RuntimeException::class); + $this->expectExceptionMessage(\sprintf('The HTTP status code "999" of operation "_api_InvalidExceptionToStatusOperation_get" of resource "%s" is not valid.', InvalidExceptionToStatusOperation::class)); + + $factory->create(InvalidExceptionToStatusOperation::class); + } + public function testWithParameters(): void { $attributeResourceMetadataCollectionFactory = new AttributesResourceMetadataCollectionFactory(); @@ -435,7 +447,7 @@ public function testDuplicateOperationNameThrows(): void { $factory = new AttributesResourceMetadataCollectionFactory(); - $this->expectException(\ApiPlatform\Metadata\Exception\RuntimeException::class); + $this->expectException(RuntimeException::class); $this->expectExceptionMessageMatches('/_api_\/forms\/\{id\}\/submit\{\._format\}/'); $factory->create(SameNameDifferentMethodOperations::class);