Last active
April 8, 2020 21:40
-
-
Save mkoert/642e804035f1860dc09bd92ff327fa77 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php declare(strict_types=1); | |
namespace ApiMhv\Http\EventListener; | |
use Symfony\Component\HttpFoundation\Response; | |
use Symfony\Component\HttpFoundation\JsonResponse; | |
use Symfony\Component\HttpKernel\Event\ExceptionEvent; | |
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; | |
// use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | |
class ExceptionListener | |
{ | |
public function onKernelException(ExceptionEvent $event) | |
{ | |
// You get the exception object from the received event | |
$exception = $event->getThrowable(); | |
$message = sprintf( | |
'%s with code: %s', | |
$exception->getMessage(), | |
$exception->getCode() | |
); | |
// Customize your response object to display the exception details | |
// if($contentType) | |
$response = new JsonResponse(); | |
$response->setContent($message); | |
// HttpExceptionInterface is a special type of exception that | |
// holds status code and header details | |
if ($exception instanceof HttpExceptionInterface) { | |
$response->setStatusCode($exception->getStatusCode()); | |
$response->headers->replace($exception->getHeaders()); | |
} elseif ($exception instanceof NotFoundHttpException) { | |
$response->setContent('{"errors": "not_found": "'.$message.'"}'); | |
} else { | |
$response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR); | |
} | |
// sends the modified response object to the event | |
$event->setResponse($response); | |
} | |
} | |
---- | |
<?php declare(strict_types=1); | |
namespace ApiMhv\Http\EventListener; | |
use Symfony\Component\HttpFoundation\Response; | |
class ExceptionResponseStrategyMap extends CoreFoundExceptionResponseStrategy | |
{ | |
protected $map = []; | |
public function addResponse($key, ExceptionStrategyResponse $response): self | |
{ | |
$map[$key] = $response; | |
return self; | |
} | |
public function getResponse($key, Response $response, \Exception $exception) | |
{ | |
return $map[$key]->handle($response, $exception); | |
} | |
} | |
---- | |
<?php declare(strict_types=1); | |
namespace ApiMhv\Http\EventListener; | |
use Symfony\Component\HttpFoundation\Response; | |
class NotFoundExceptionResponseStrategy extends CoreFoundExceptionResponseStrategy | |
{ | |
public function handle(Response $response, \Exception $exception) | |
{ | |
$response->setHeaders($response, $exception); | |
$response->setStatusCode($response, $exception); | |
$response->setContent('{"errors": "not_found": "'.$message.'"}'); | |
return $response; | |
} | |
} | |
---- | |
<?php declare(strict_types=1); | |
namespace ApiMhv\Http\EventListener; | |
use Symfony\Component\HttpFoundation\Response; | |
abstract class CoreFoundExceptionStrategyResponse | |
{ | |
protected function setStatusCode(Response $response, $exception): Response | |
{ | |
$response->setStatusCode($exception->getStatusCode()); | |
return $response; | |
} | |
protected function setHeaders(Response $response, $exception): Resonse | |
{ | |
$response->headers->replace($exception->getHeaders()); | |
return $response; | |
} | |
} | |
---- | |
<?php declare(strict_types=1); | |
namespace ApiMhv\Http\EventListener; | |
use Symfony\Component\HttpFoundation\JsonResponse; | |
interface ExceptionStrategyResponse | |
{ | |
public function handle(JsonResponse $response, $exception); | |
} | |
yvoyer
commented
Apr 8, 2020
•
$strategy = new ArrayStrategy(
new NullStrategy(),
new NotFoundStrategy(),
new ServerErrorStrategy()
);
$listener = new ExceptionListner($strategy);
$listener->onKernelEvent(new Exception('whatever'));
$response // would be done
interface ResponseFailure
{
public function createResponse(Response $response, \Throwable $exception): Response;
public function supportsExecption(\Throwable $execption): bool;
}
final class ClosureStrategy implements YourStrrategy
{
private $closure;
public function __construct(\Closure $closure) {}
public function modifyResponse(Response $response, \Throwable $exception): Response
{
$closure = $this->closure;
return $closure($response, $exception);
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment