Skip to content

Instantly share code, notes, and snippets.

@TimoBakx
Last active October 3, 2019 15:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TimoBakx/84058161612b6e6b3bfdfecb9bdd7bf8 to your computer and use it in GitHub Desktop.
Save TimoBakx/84058161612b6e6b3bfdfecb9bdd7bf8 to your computer and use it in GitHub Desktop.
Exception wrapper for Api Platform
<?php
declare(strict_types=1);
/**
* This is an example of the exception interfaces I use to map my internal exceptions. They're just empty.
*/
namespace App\Api\Exception;
use Throwable;
interface NotFound extends Throwable
{
}
<?php
declare(strict_types=1);
/**
* This is the interface to more easily register event listeners, configured as follows in services.yaml:
*
* services:
* _instanceof:
* App\Util\EventListener\Symfony\OnKernelException:
* tags: [{name: 'kernel.event_listener', event: 'kernel.exception', priority: -10, lazy: true}]
*/
namespace App\Util\EventListener\Symfony;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
interface OnKernelException
{
public function __invoke(ExceptionEvent $event): void;
}
<?php
declare(strict_types=1);
/**
* This is the mapper that wraps internal exceptions in HTTP exceptions when those exceptions implement one of the exception interfaces.
*/
namespace App\Api\Exception;
use App\Util\EventListener\Symfony\OnKernelException;
use Exception;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
final class WrapExceptionsForHttp implements OnKernelException
{
private const MAPPING = [
NotFound::class => NotFoundHttpException::class,
RequiredParameterMissing::class => BadRequestHttpException::class,
InvalidParameter::class => BadRequestHttpException::class,
AuthorizationFault::class => AccessDeniedHttpException::class,
NotAllowed::class => AccessDeniedHttpException::class,
AuthenticationFailed::class => UnauthorizedHttpException::class,
Unprocessable::class => UnprocessableEntityHttpException::class,
];
public function __invoke(ExceptionEvent $event): void
{
$event->setException($this->wrapException($event->getException()));
}
private function wrapException(Exception $exception): Exception
{
foreach (self::MAPPING as $class => $wrapperClass) {
if (!$exception instanceof $class) {
continue;
}
return new $wrapperClass($exception->getMessage(), $exception);
}
return $exception;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment