Skip to content

Commit 4adc075

Browse files
authored
fix: multiple error routes #6214 (#6263)
1 parent cf20566 commit 4adc075

File tree

7 files changed

+38
-3
lines changed

7 files changed

+38
-3
lines changed

src/Hydra/Serializer/DocumentationNormalizer.php

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use ApiPlatform\Metadata\ApiProperty;
2121
use ApiPlatform\Metadata\ApiResource;
2222
use ApiPlatform\Metadata\CollectionOperationInterface;
23+
use ApiPlatform\Metadata\ErrorResource;
2324
use ApiPlatform\Metadata\HttpOperation;
2425
use ApiPlatform\Metadata\Operation;
2526
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
@@ -29,6 +30,7 @@
2930
use ApiPlatform\Metadata\ResourceClassResolverInterface;
3031
use ApiPlatform\Metadata\UrlGeneratorInterface;
3132
use ApiPlatform\Serializer\CacheableSupportsMethodInterface;
33+
use ApiPlatform\Symfony\Validator\Exception\ValidationException;
3234
use Symfony\Component\PropertyInfo\Type;
3335
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
3436
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
@@ -60,6 +62,10 @@ public function normalize(mixed $object, ?string $format = null, array $context
6062
$resourceMetadataCollection = $this->resourceMetadataFactory->create($resourceClass);
6163

6264
$resourceMetadata = $resourceMetadataCollection[0];
65+
if ($resourceMetadata instanceof ErrorResource && ValidationException::class === $resourceMetadata->getClass()) {
66+
continue;
67+
}
68+
6369
$shortName = $resourceMetadata->getShortName();
6470
$prefixedShortName = $resourceMetadata->getTypes()[0] ?? "#$shortName";
6571
$this->populateEntrypointProperties($resourceMetadata, $shortName, $prefixedShortName, $entrypointProperties, $resourceMetadataCollection);

src/Metadata/Resource/Factory/OperationDefaultsTrait.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ private function getOperationWithDefaults(ApiResource $resource, Operation $oper
202202
throw new RuntimeException(sprintf('Operation should be an instance of "%s"', HttpOperation::class));
203203
}
204204

205-
if ($operation->getRouteName()) {
205+
if (!$operation->getName() && $operation->getRouteName()) {
206206
/** @var HttpOperation $operation */
207207
$operation = $operation->withName($operation->getRouteName());
208208
}

src/Metadata/Resource/Factory/UriTemplateResourceMetadataCollectionFactory.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public function create(string $resourceClass): ResourceMetadataCollection
7575
$operation = $operation->withName($routeName);
7676
}
7777

78-
$operations->add($routeName, $operation);
78+
$operations->add($operation->getName(), $operation);
7979
continue;
8080
}
8181

src/State/ApiResource/Error.php

+9
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
operations: [
3434
new Operation(
3535
name: '_api_errors_problem',
36+
routeName: 'api_errors',
3637
outputFormats: ['json' => ['application/problem+json']],
3738
normalizationContext: [
3839
'groups' => ['jsonproblem'],
@@ -42,6 +43,7 @@
4243
),
4344
new Operation(
4445
name: '_api_errors_hydra',
46+
routeName: 'api_errors',
4547
outputFormats: ['jsonld' => ['application/problem+json']],
4648
normalizationContext: [
4749
'groups' => ['jsonld'],
@@ -52,13 +54,18 @@
5254
),
5355
new Operation(
5456
name: '_api_errors_jsonapi',
57+
routeName: 'api_errors',
5558
outputFormats: ['jsonapi' => ['application/vnd.api+json']],
5659
normalizationContext: [
5760
'groups' => ['jsonapi'],
5861
'skip_null_values' => true,
5962
'rfc_7807_compliant_errors' => true,
6063
],
6164
),
65+
new Operation(
66+
name: '_api_errors',
67+
routeName: 'api_errors'
68+
),
6269
],
6370
provider: 'api_platform.state.error_provider',
6471
graphQlOperations: []
@@ -120,12 +127,14 @@ public static function createFromException(\Exception|\Throwable $exception, int
120127
}
121128

122129
#[Ignore]
130+
#[ApiProperty(readable: false)]
123131
public function getHeaders(): array
124132
{
125133
return $this->headers;
126134
}
127135

128136
#[Ignore]
137+
#[ApiProperty(readable: false)]
129138
public function getStatusCode(): int
130139
{
131140
return $this->status;

src/Symfony/Bundle/Resources/config/routing/api.xml

+11
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,15 @@
1414
<requirement key="index">index</requirement>
1515
</route>
1616

17+
<route id="api_errors" path="/errors/{status}">
18+
<default key="_controller">api_platform.action.not_exposed</default>
19+
<default key="status">500</default>
20+
21+
<requirement key="status">\d+</requirement>
22+
</route>
23+
24+
<route id="api_validation_errors" path="/validation_errors/{id}">
25+
<default key="_controller">api_platform.action.not_exposed</default>
26+
</route>
27+
1728
</routes>

src/Symfony/Routing/IriConverter.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,9 @@ private function generateSymfonyRoute(object|string $resource, int $referenceTyp
186186
}
187187

188188
try {
189-
return $this->router->generate($operation->getName(), $identifiers, $operation->getUrlGenerationStrategy() ?? $referenceType);
189+
$routeName = $operation instanceof HttpOperation ? ($operation->getRouteName() ?? $operation->getName()) : $operation->getName();
190+
191+
return $this->router->generate($routeName, $identifiers, $operation->getUrlGenerationStrategy() ?? $referenceType);
190192
} catch (RoutingExceptionInterface $e) {
191193
throw new InvalidArgumentException(sprintf('Unable to generate an IRI for the item of type "%s"', $operation->getClass()), $e->getCode(), $e);
192194
}

src/Symfony/Validator/Exception/ValidationException.php

+7
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,15 @@
4040
operations: [
4141
new ErrorOperation(
4242
name: '_api_validation_errors_problem',
43+
routeName: 'api_validation_errors',
4344
outputFormats: ['json' => ['application/problem+json']],
4445
normalizationContext: ['groups' => ['json'],
4546
'skip_null_values' => true,
4647
'rfc_7807_compliant_errors' => true,
4748
]),
4849
new ErrorOperation(
4950
name: '_api_validation_errors_hydra',
51+
routeName: 'api_validation_errors',
5052
outputFormats: ['jsonld' => ['application/problem+json']],
5153
links: [new Link(rel: ContextBuilderInterface::JSONLD_NS.'error', href: 'http://www.w3.org/ns/hydra/error')],
5254
normalizationContext: [
@@ -57,9 +59,14 @@
5759
),
5860
new ErrorOperation(
5961
name: '_api_validation_errors_jsonapi',
62+
routeName: 'api_validation_errors',
6063
outputFormats: ['jsonapi' => ['application/vnd.api+json']],
6164
normalizationContext: ['groups' => ['jsonapi'], 'skip_null_values' => true, 'rfc_7807_compliant_errors' => true]
6265
),
66+
new ErrorOperation(
67+
name: '_api_validation_errors',
68+
routeName: 'api_validation_errors'
69+
),
6370
],
6471
graphQlOperations: []
6572
)]

0 commit comments

Comments
 (0)