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.


Cevap içeriği


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}]
}
}

Controller


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

Exception


ApiExceptionInterface


namespace Inanzzz\ApplicationBundle\Exception;

interface ApiExceptionInterface
{
}

NotFoundException


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);
}
}

BadRequestException


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);
}
}

ApiExceptionListener


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 }

Test


404 Not Found


Adres: GET /not-found-exception.


# 1
{
"error": {
"code": 404,
"messages": []
}
}

# 2
{
"error": {
"code": 404,
"messages": [
"Order you are looking for cannot be found."
]
}
}

400 Bad Request


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."
]
}
}