10/02/2017 - SYMFONY
Bu örneğimizde standart hata mesaj kalıbı yaratmak için kullanılacak olan, özel olarak hazırlanmış hata exception class ve event listener kullanacağız. Sadece iki tane exception kullanıyoruz ama isterseniz kendiniz daha fazla exception class yaratabilirsiniz. Diğer kodları değiştirmenize gerek yok.
Aşağıda string message
yerine array olarak messages
kullanmamızın nedeni, bazı doğrulama işlemleri birden fazla hata mesajı yaratabilirler. Aşağıdaki testlere baktığınızda ne demek istediğimi daha iyi anlayacaksınız.
{
"error": {
"code": {An inreger error code goes here which matches header status code},
"messages": [{Zero or more error messages}]
}
}
Exception'ları kullanma şekilleri aşağıda listelenmiştir.
namespace Inanzzz\ApplicationBundle\Controller;
use Inanzzz\ApplicationBundle\Exception\BadRequestException;
use Inanzzz\ApplicationBundle\Exception\NotFoundException;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\Response;
/**
* @Route("", service="inanzzz_application.controller.default")
*/
class DefaultController
{
/**
* @Method({"GET"})
* @Route("/not-found-exception")
*
* @return Response
*
* @throws NotFoundException
*/
public function notFoundExceptionAction()
{
throw new NotFoundException();
throw new NotFoundException('Order you are looking for cannot be found.');
}
/**
* @Method({"GET"})
* @Route("/bad-request-exception")
*
* @return Response
*
* @throws BadRequestException
*/
public function badRequestExceptionAction()
{
throw new BadRequestException();
throw new BadRequestException([]);
throw new BadRequestException(['Name field is required.']);
throw new BadRequestException(['Name field is required.', 'Postcode field is required.']);
}
}
services:
inanzzz_application.controller.default:
class: Inanzzz\ApplicationBundle\Controller\DefaultController
namespace Inanzzz\ApplicationBundle\Exception;
interface ApiExceptionInterface
{
}
Ya hiç ya da sadece bir tane string olarak hata mesajı kabul eder. 404 Not Found
hatasını oluşturur.
namespace Inanzzz\ApplicationBundle\Exception;
use Exception;
use Symfony\Component\HttpFoundation\Response;
class NotFoundException extends Exception implements ApiExceptionInterface
{
public function __construct($message = null)
{
parent::__construct($message, Response::HTTP_NOT_FOUND);
}
}
Ya hiç ya da birden fazla array olarak hata mesajı kabul eder. 400 Bad Request
hatasını oluşturur.
namespace Inanzzz\ApplicationBundle\Exception;
use Exception;
use Symfony\Component\HttpFoundation\Response;
class BadRequestException extends Exception implements ApiExceptionInterface
{
public function __construct(
array $message = [],
$code = Response::HTTP_BAD_REQUEST,
Exception $previous = null
) {
parent::__construct(json_encode($message), $code, $previous);
}
}
namespace Inanzzz\ApplicationBundle\EventListener;
use Inanzzz\ApplicationBundle\Exception\ApiExceptionInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
class ApiExceptionListener
{
public function onKernelException(GetResponseForExceptionEvent $event)
{
if (!$event->getException() instanceof ApiExceptionInterface) {
return;
}
$response = new JsonResponse($this->buildResponseData($event->getException()));
$response->setStatusCode($event->getException()->getCode());
$event->setResponse($response);
}
private function buildResponseData(ApiExceptionInterface $exception)
{
$messages = json_decode($exception->getMessage());
if (!is_array($messages)) {
$messages = $exception->getMessage() ? [$exception->getMessage()] : [];
}
return [
'error' => [
'code' => $exception->getCode(),
'messages' => $messages
]];
}
}
services:
inanzzz_application.listener.api_exception:
class: Inanzzz\ApplicationBundle\EventListener\ApiExceptionListener
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
Adres: GET /not-found-exception
.
# 1
{
"error": {
"code": 404,
"messages": []
}
}
# 2
{
"error": {
"code": 404,
"messages": [
"Order you are looking for cannot be found."
]
}
}
Adres: GET /bad-request-exception
.
# 1
{
"error": {
"code": 400,
"messages": []
}
}
# 2
{
"error": {
"code": 400,
"messages": []
}
}
# 3
{
"error": {
"code": 400,
"messages": [
"Name field is required."
]
}
}
# 4
{
"error": {
"code": 400,
"messages": [
"Name field is required.",
"Postcode field is required."
]
}
}