Skip to content

Cannot generate IRI errors when enabling rfc_7807_compliant_errors #6718

@darthf1

Description

@darthf1

API Platform version(s) affected: 3.4.3

Description
I'm trying to enable rfc_7807_compliant_errors as an upgrade path to v4. When I do this, in my project, not only the error output changes (obviously), but I also get:

ApiPlatform\Metadata\Exception\InvalidArgumentException: Unable to generate an IRI for the item of type  ....

How to reproduce
I have the following code:

<?php

namespace App;

#[ApiResource(
    shortName: 'Organisation',
    operations: [
        new Get(
            uriTemplate: '/organisations/{id}',
            security: "is_granted('" . OrganisationVoter::ATTRIBUTE_ORGANISATION_READ . "', object)",
            provider: ItemProvider::class,
        ),
        new Get(
            uriTemplate: '/users/{userId}/organisation',
            uriVariables: [
                'userId' => new Link(
                    fromClass: UserProjection::class,
                ),
            ],
            normalizationContext: [
                'item_uri_template' => '/organisations/{id}',
                'groups' => [self::NORMALIZATION_GROUP],
            ],
            provider: UserOrganisationProvider::class,
        ),
    ],
)]
class Organisation {}

I have two test cases:

  • fetching an Organisation for a given user, and the user has access to the Organisation, it returns the Organisation
  • fetching an Organisation for a given user, and the user does not have access to an Organisation, it returns HTTP 404.

The following happens:

  • With rfc_7807_compliant_errors to false, both test cases succeed.
  • With rfc_7807_compliant_errors to true, the second test case throws: ApiPlatform\Metadata\Exception\InvalidArgumentException: Unable to generate an IRI for the item of type "App\Organisation". When I then remove the line 'item_uri_template' => '/organisations/{id}', from the operation, the test succeeds again.

Additional Context
My (partial) config:

<?php

declare(strict_types=1);

use ApiPlatform\Metadata\Exception\InvalidArgumentException;
use ApiPlatform\Validator\Exception\ValidationException;
use Doctrine\ORM\OptimisticLockException;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Messenger\Exception\ValidationFailedException;
use Symfony\Component\Serializer\Exception\ExceptionInterface;

return static function (ContainerConfigurator $containerConfigurator): void {
    $containerConfigurator->extension('api_platform', [
        'defaults' => [
            'collectDenormalizationErrors' => true,
            'extra_properties' => [
                'standard_put' => true,
                'rfc_7807_compliant_errors' => true,
            ],
            'pagination_client_enabled' => true,
            'pagination_client_items_per_page' => true,
            'pagination_items_per_page' => 30,
            'pagination_maximum_items_per_page' => 100,
            'stateless' => true,
        ],
        'enable_link_security' => true,
        'exception_to_status' => [
            ExceptionInterface::class => Response::HTTP_BAD_REQUEST,
            InvalidArgumentException::class => Response::HTTP_BAD_REQUEST,
            OptimisticLockException::class => Response::HTTP_CONFLICT,
            ValidationException::class => Response::HTTP_UNPROCESSABLE_ENTITY,
            ValidationFailedException::class => Response::HTTP_UNPROCESSABLE_ENTITY,
        ],
        'keep_legacy_inflector' => false,
        'use_symfony_listeners' => true,
        'serializer' => [
            'hydra_prefix' => false,
        ],
    ]);
};

Full stacktrace:

ApiPlatform\Metadata\Exception\InvalidArgumentException: Unable to generate an IRI for the item of type "App\Organisation"
/home/www/app/vendor/api-platform/core/src/Symfony/Routing/IriConverter.php:194
/home/www/app/vendor/api-platform/core/src/Symfony/Routing/IriConverter.php:171
/home/www/app/vendor/api-platform/core/src/JsonLd/Serializer/ItemNormalizer.php:129
/home/www/app/vendor/api-platform/core/src/JsonLd/Serializer/ErrorNormalizer.php:31
/home/www/app/vendor/symfony/serializer/Serializer.php:150
/home/www/app/vendor/symfony/serializer/Serializer.php:129
/home/www/app/vendor/api-platform/core/src/State/Processor/SerializeProcessor.php:79
/home/www/app/vendor/api-platform/core/src/Symfony/EventListener/SerializeListener.php:102
/home/www/app/vendor/symfony/event-dispatcher/Debug/WrappedListener.php:115
/home/www/app/vendor/symfony/event-dispatcher/EventDispatcher.php:206
/home/www/app/vendor/symfony/event-dispatcher/EventDispatcher.php:56
/home/www/app/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php:122
/home/www/app/vendor/symfony/http-kernel/HttpKernel.php:188
/home/www/app/vendor/symfony/http-kernel/HttpKernel.php:76
/home/www/app/vendor/symfony/http-kernel/EventListener/ErrorListener.php:97
/home/www/app/vendor/api-platform/core/src/Symfony/EventListener/ExceptionListener.php:50
/home/www/app/vendor/symfony/event-dispatcher/Debug/WrappedListener.php:115
/home/www/app/vendor/symfony/event-dispatcher/EventDispatcher.php:206
/home/www/app/vendor/symfony/event-dispatcher/EventDispatcher.php:56
/home/www/app/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php:122
/home/www/app/vendor/symfony/http-kernel/HttpKernel.php:241
/home/www/app/vendor/symfony/http-kernel/HttpKernel.php:91
/home/www/app/vendor/symfony/http-kernel/Kernel.php:182
/home/www/app/vendor/symfony/http-kernel/HttpKernelBrowser.php:63
/home/www/app/vendor/symfony/framework-bundle/KernelBrowser.php:157
/home/www/app/vendor/symfony/browser-kit/AbstractBrowser.php:369
/home/www/app/vendor/api-platform/core/src/Symfony/Bundle/Test/Client.php:115
/home/www/app/tests/Functional/App/OrganisationTest.php:202

Caused by
ApiPlatform\Metadata\Exception\RuntimeException: Not able to retrieve identifiers.

/home/www/app/vendor/api-platform/core/src/Metadata/IdentifiersExtractor.php:139
/home/www/app/vendor/api-platform/core/src/Metadata/IdentifiersExtractor.php:90
/home/www/app/vendor/api-platform/core/src/Metadata/IdentifiersExtractor.php:60
/home/www/app/vendor/api-platform/core/src/Symfony/Routing/IriConverter.php:190
/home/www/app/vendor/api-platform/core/src/Symfony/Routing/IriConverter.php:171
/home/www/app/vendor/api-platform/core/src/JsonLd/Serializer/ItemNormalizer.php:129
/home/www/app/vendor/api-platform/core/src/JsonLd/Serializer/ErrorNormalizer.php:31
/home/www/app/vendor/symfony/serializer/Serializer.php:150
/home/www/app/vendor/symfony/serializer/Serializer.php:129
/home/www/app/vendor/api-platform/core/src/State/Processor/SerializeProcessor.php:79
/home/www/app/vendor/api-platform/core/src/Symfony/EventListener/SerializeListener.php:102
/home/www/app/vendor/symfony/event-dispatcher/Debug/WrappedListener.php:115
/home/www/app/vendor/symfony/event-dispatcher/EventDispatcher.php:206
/home/www/app/vendor/symfony/event-dispatcher/EventDispatcher.php:56
/home/www/app/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php:122
/home/www/app/vendor/symfony/http-kernel/HttpKernel.php:188
/home/www/app/vendor/symfony/http-kernel/HttpKernel.php:76
/home/www/app/vendor/symfony/http-kernel/EventListener/ErrorListener.php:97
/home/www/app/vendor/api-platform/core/src/Symfony/EventListener/ExceptionListener.php:50
/home/www/app/vendor/symfony/event-dispatcher/Debug/WrappedListener.php:115
/home/www/app/vendor/symfony/event-dispatcher/EventDispatcher.php:206
/home/www/app/vendor/symfony/event-dispatcher/EventDispatcher.php:56
/home/www/app/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php:122
/home/www/app/vendor/symfony/http-kernel/HttpKernel.php:241
/home/www/app/vendor/symfony/http-kernel/HttpKernel.php:91
/home/www/app/vendor/symfony/http-kernel/Kernel.php:182
/home/www/app/vendor/symfony/http-kernel/HttpKernelBrowser.php:63
/home/www/app/vendor/symfony/framework-bundle/KernelBrowser.php:157
/home/www/app/vendor/symfony/browser-kit/AbstractBrowser.php:369
/home/www/app/vendor/api-platform/core/src/Symfony/Bundle/Test/Client.php:115
/home/www/app/tests/Functional/App/OrganisationTest.php:202

Caused by
Symfony\Component\HttpKernel\Exception\NotFoundHttpException: Not Found

/home/www/app/vendor/api-platform/core/src/State/Provider/ReadProvider.php:94
/home/www/app/vendor/api-platform/core/src/Symfony/Validator/State/ParameterValidatorProvider.php:87
/home/www/app/vendor/api-platform/core/src/State/Provider/ParameterProvider.php:103
/home/www/app/vendor/api-platform/core/src/Symfony/Bundle/SwaggerUi/SwaggerUiProvider.php:50
/home/www/app/vendor/api-platform/core/src/Symfony/Security/State/AccessCheckerProvider.php:62
/home/www/app/vendor/api-platform/core/src/State/Provider/SecurityParameterProvider.php:39
/home/www/app/vendor/api-platform/core/src/Symfony/Security/State/LinkedReadProvider.php:42
/home/www/app/vendor/api-platform/core/src/Symfony/Security/State/LinkAccessCheckerProvider.php:40
/home/www/app/vendor/api-platform/core/src/Symfony/EventListener/ReadListener.php:95
/home/www/app/vendor/symfony/event-dispatcher/Debug/WrappedListener.php:115
/home/www/app/vendor/symfony/event-dispatcher/EventDispatcher.php:206
/home/www/app/vendor/symfony/event-dispatcher/EventDispatcher.php:56
/home/www/app/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php:122
/home/www/app/vendor/symfony/http-kernel/HttpKernel.php:159
/home/www/app/vendor/symfony/http-kernel/HttpKernel.php:76
/home/www/app/vendor/symfony/http-kernel/Kernel.php:182
/home/www/app/vendor/symfony/http-kernel/HttpKernelBrowser.php:63
/home/www/app/vendor/symfony/framework-bundle/KernelBrowser.php:157
/home/www/app/vendor/symfony/browser-kit/AbstractBrowser.php:369
/home/www/app/vendor/api-platform/core/src/Symfony/Bundle/Test/Client.php:115
/home/www/app/tests/Functional/App/OrganisationTest.php:202

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions