[Laravel5] Rest API에서 에러발생시 JSON 포맷으로 Response를 보내는 방법

Posted on 2017-03-22 23:34:06


Laravel Rest API에서 에러가 발생했을 때, http response가 json이 아닌 html 포맷으로 넘어오는 문제가 있었다. 클라이언트에서 http request를 보낼 때, http header에 Accept 항목을 "application/json"으로 설정했는데도 불구하고 html 포맷으로 response가 왔다.

let headers: HTTPHeaders = [
    "Accept":   "application/json",
    ...
]

 

이 문제를 해결하려고 구글에서 삽질하다가 stack overflow에서 괜찮은 해결책을 발견했다. App\Exceptions\Handler 클래스에서 아래 파란색으로 표시된 코드를 추가해주면 된다. 

• app/Exceptions/Handler.php

<?php

namespace App\Exceptions;

...
use Illuminate\Http\Response;

class Handler extends ExceptionHandler
{
    ...

    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $exception
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $exception)
    {
// json format을 리턴해야 하는지 체크(for API)
if ($request->wantsJson()) { return $this->renderExceptionAsJson($request, $exception); } if( ($exception instanceof AuthenticationException) || ($exception instanceof NotFoundHttpException) || ($exception instanceof ModelNotFoundException) || ($exception instanceof ValidationException) ) { return parent::render($request, $exception); } return response()->view('errors.500', [], 500); } /** * Render an exception into a JSON response * * @param $request * @param Exception $exception * @return SymfonyResponse */ protected function renderExceptionAsJson($request, Exception $exception) { // Currently converts AuthorizationException to 403 HttpException // and ModelNotFoundException to 404 NotFoundHttpException $exception = $this->prepareException($exception); // Default response $response = [ 'error' => 'Sorry, something went wrong.' ]; // Add debug info if app is in debug mode if (config('app.debug')) { // Add the exception class name, message and stack trace to response $response['exception'] = get_class($exception); // Reflection might be better here $response['message'] = $exception->getMessage(); // $response['trace'] = $exception->getTrace(); } $status = 400; // Build correct status codes and status texts switch ($exception) { case $exception instanceof ValidationException: return $this->convertValidationExceptionToResponse($exception, $request); case $exception instanceof AuthenticationException: $status = 401; $response['error'] = Response::$statusTexts[$status]; break; case $this->isHttpException($exception): $status = $exception->getStatusCode(); $response['error'] = Response::$statusTexts[$status]; break; default: break; } return response()->json($response, $status); } ... }

 



Related Posts

[Laravel5] log rotation 설정 2017-02-26 21:45:15
[Laravel5.4] migration시에 "Specified key was too long" 에러가 발생하는 문제의 해결방법 2017-02-18 23:45:28
[Laravel5] blade template에서 변수를 선언하는 방법 2017-02-17 20:32:52
[Laravel5] timestamps(updated_at column)를 touch하지 않고 update하는 방법 2017-02-09 16:31:18
[Laravel5] altisan command 사용법 요약 2017-02-02 21:38:55