Skip to content

Commit 3ca5991

Browse files
authored
fix(hydra): hydra_prefix on errors (#6704)
* fix(hydra): hydra_prefix on errors * doc: remove warning from changelog * review
1 parent 6904923 commit 3ca5991

File tree

5 files changed

+70
-6
lines changed

5 files changed

+70
-6
lines changed

CHANGELOG.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@
1212
* [afe7d47d7](https://github.com/api-platform/core/commit/afe7d47d7b7ba6c8591bfb60137a65d1fa1fe38f) fix(metadata): passing class as parameter in XML ApiResource's definition (#6659)
1313
* [b93ee467c](https://github.com/api-platform/core/commit/b93ee467c69253e0cfe60e75b48a5c7aa683474a) fix(metadata): overwriting XML ApiResource definition by YAML ApiResource definition (#6660)
1414

15-
> [!WARNING]
16-
> Hydra prefix on errors is breaking, read `title` not `hydra:title`. The `hydra_prefix` flag doesn't apply to errors as it provided redundant information (both `hydra:title` and `title` were available)
17-
1815
## v3.4.1
1916

2017
### Bug fixes

features/hydra/error.feature

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@ Feature: Error handling
1717
And the header "Link" should contain '<http://www.w3.org/ns/hydra/error>; rel="http://www.w3.org/ns/json-ld#error"'
1818
And the JSON node "type" should exist
1919
And the JSON node "title" should be equal to "An error occurred"
20+
And the JSON node "hydra:title" should be equal to "An error occurred"
2021
And the JSON node "detail" should exist
2122
And the JSON node "description" should exist
23+
And the JSON node "hydra:description" should exist
2224
And the JSON node "trace" should exist
2325
And the JSON node "status" should exist
2426
And the JSON node "@context" should not exist
@@ -47,6 +49,8 @@ Feature: Error handling
4749
],
4850
"detail": "name: This value should not be blank.",
4951
"title": "An error occurred",
52+
"hydra:title": "An error occurred",
53+
"hydra:description": "name: This value should not be blank.",
5054
"description": "name: This value should not be blank.",
5155
"type": "/validation_errors/c1051bb4-d103-4f74-8988-acbcafc7fdc3"
5256
}

src/JsonLd/ContextBuilder.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
namespace ApiPlatform\JsonLd;
1515

1616
use ApiPlatform\JsonLd\Serializer\HydraPrefixTrait;
17-
use ApiPlatform\Metadata\Error;
1817
use ApiPlatform\Metadata\Get;
1918
use ApiPlatform\Metadata\HttpOperation;
2019
use ApiPlatform\Metadata\IriConverterInterface;
@@ -185,7 +184,7 @@ private function getResourceContextWithShortname(string $resourceClass, int $ref
185184
}
186185
}
187186

188-
if (false === ($this->defaultContext[self::HYDRA_CONTEXT_HAS_PREFIX] ?? true) || $operation instanceof Error) {
187+
if (false === ($this->defaultContext[self::HYDRA_CONTEXT_HAS_PREFIX] ?? true)) {
189188
return ['http://www.w3.org/ns/hydra/context.jsonld', $context];
190189
}
191190

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\JsonLd\Serializer;
15+
16+
use ApiPlatform\State\ApiResource\Error;
17+
use ApiPlatform\Symfony\Validator\Exception\ValidationException as SymfonyValidationException;
18+
use ApiPlatform\Validator\Exception\ValidationException;
19+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
20+
21+
final class ErrorNormalizer implements NormalizerInterface
22+
{
23+
use HydraPrefixTrait;
24+
25+
public function __construct(private readonly NormalizerInterface $inner, private readonly array $defaultContext = [])
26+
{
27+
}
28+
29+
public function normalize(mixed $object, ?string $format = null, array $context = []): array|string|int|float|bool|\ArrayObject|null
30+
{
31+
$normalized = $this->inner->normalize($object, $format, $context);
32+
$hydraPrefix = $this->getHydraPrefix($context + $this->defaultContext);
33+
if (!$hydraPrefix) {
34+
return $normalized;
35+
}
36+
37+
if (isset($normalized['description'])) {
38+
$normalized['hydra:description'] = $normalized['description'];
39+
}
40+
41+
if (isset($normalized['title'])) {
42+
$normalized['hydra:title'] = $normalized['title'];
43+
}
44+
45+
return $normalized;
46+
}
47+
48+
public function supportsNormalization(mixed $data, ?string $format = null, array $context = []): bool
49+
{
50+
return $this->inner->supportsNormalization($data, $format, $context)
51+
&& (is_a($data, Error::class) || is_a($data, ValidationException::class) || is_a($data, SymfonyValidationException::class));
52+
}
53+
54+
public function getSupportedTypes(?string $format): array
55+
{
56+
return $this->inner->getSupportedTypes($format);
57+
}
58+
}

src/Symfony/Bundle/Resources/config/jsonld.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@
3636
<tag name="serializer.normalizer" priority="-890" />
3737
</service>
3838

39+
<service id="api_platform.jsonld.normalizer.error" class="ApiPlatform\JsonLd\Serializer\ErrorNormalizer" public="false">
40+
<argument type="service" id="api_platform.jsonld.normalizer.item" />
41+
<argument>%api_platform.serializer.default_context%</argument>
42+
<tag name="serializer.normalizer" priority="-880" />
43+
</service>
44+
3945
<service id="api_platform.jsonld.normalizer.object" class="ApiPlatform\JsonLd\Serializer\ObjectNormalizer" public="false">
4046
<argument type="service" id="serializer.normalizer.object" />
4147
<argument type="service" id="api_platform.iri_converter" />
@@ -46,7 +52,7 @@
4652
</service>
4753

4854
<service id="api_platform.jsonld.normalizer.validation_exception" class="ApiPlatform\Symfony\Validator\Serializer\ValidationExceptionNormalizer" public="false">
49-
<argument type="service" id="api_platform.jsonld.normalizer.item" />
55+
<argument type="service" id="api_platform.jsonld.normalizer.error" />
5056
<argument type="service" id="api_platform.name_converter" on-invalid="ignore" />
5157

5258
<tag name="serializer.normalizer" priority="-800" />

0 commit comments

Comments
 (0)