Api Platform conference
Register now
API Platform Conference
September 19-20, 2024 | Lille & online

The international conference on the API Platform Framework

API Platform Conference 2024: meet the best PHP, JavaScript and API experts

Learn more about the event, register for the conference, and get ready for two days of inspiration, ideas, and knowledge-sharing with our incredible lineup of renowned specialists and advocates.

Register now

Error provider to translate exception messages

design state

Note that we use the following configuration:

           rfc_7807_compliant_errors: true

To customize the API Platform response, replace the api_platform.state.error_provider with your own provider:

// src/App/ApiResource.php
namespace App\ApiResource;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\Operation;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
    operations: [
        new Get(provider: Book::class.'::provide'),
class Book
    public function __construct(
        public readonly int $id = 1,
        public readonly string $name = 'Anon',
    ) {
    public static function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
        throw new BadRequestHttpException('something is not right');

// src/App/State.php
namespace App\State;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ApiResource\Error;
use ApiPlatform\State\ProviderInterface;
Note that we need to replace the “api_platform.state.error_provider” service, this is done later in this guide.
final class ErrorProvider implements ProviderInterface
    public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
        $request = $context['request'];
        if (!$request || !($exception = $request->attributes->get('exception'))) {
            throw new \RuntimeException();
        /** @var \ApiPlatform\Metadata\HttpOperation $operation */
        $status = $operation->getStatus() ?? 500;
You don’t have to use this, you can use a Response, an array or any object (preferably a resource that API Platform can handle).
        $error = Error::createFromException($exception, $status);
care about hiding informations as this can be a security leak
        if ($status >= 500) {
            $error->setDetail('Something went wrong');
        } else {
You can handle translation here with the Translator
            $error->setDetail(str_replace('something is not right', 'les calculs ne sont pas bons', $exception->getMessage()));
        return $error;
This is replacing the service, the “key” is important as this is the provider we will look for when handling an exception.
// src/App/DependencyInjection.php
namespace App\DependencyInjection;
use App\State\ErrorProvider;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
function configure(ContainerConfigurator $configurator): void
    $services = $configurator->services();
        ->tag('api_platform.state_provider', ['key' => 'api_platform.state.error_provider']);

// src/App/Tests.php
namespace App\Tests;
use ApiPlatform\Playground\Test\TestGuideTrait;
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
final class BookTest extends ApiTestCase
    use TestGuideTrait;
    public function testBookDoesNotExists(): void
        static::createClient()->request('GET', '/books/1', options: ['headers' => ['accept' => 'application/ld+json']]);
            'detail' => 'les calculs ne sont pas bons',

// src/App/Playground.php
namespace App\Playground;
use Symfony\Component\HttpFoundation\Request;
function request(): Request
    return Request::create('/books/1.jsonld', 'GET');

You can also help us improve this guide.

Made with love by

Les-Tilleuls.coop can help you design and develop your APIs and web projects, and train your teams in API Platform, Symfony, Next.js, Kubernetes and a wide range of other technologies.

Learn more

Copyright © 2023 Kévin Dunglas

Sponsored by Les-Tilleuls.coop