Laravel 5: Handle exceptions when request wants JSON Laravel 5: Handle exceptions when request wants JSON ajax ajax

Laravel 5: Handle exceptions when request wants JSON


I'm going to take a shot at this one myself taking into account the answer given by @Wader and the comments from @Tyler Crompton:

app/Exceptions/Handler.php

/** * Render an exception into an HTTP response. * * @param  \Illuminate\Http\Request  $request * @param  \Exception $e * @return \Illuminate\Http\Response */public function render($request, Exception $e){    // If the request wants JSON (AJAX doesn't always want JSON)    if ($request->wantsJson()) {        // Define the response        $response = [            'errors' => 'Sorry, something went wrong.'        ];        // If the app is in debug mode        if (config('app.debug')) {            // Add the exception class name, message and stack trace to response            $response['exception'] = get_class($e); // Reflection might be better here            $response['message'] = $e->getMessage();            $response['trace'] = $e->getTrace();        }        // Default response of 400        $status = 400;        // If this exception is an instance of HttpException        if ($this->isHttpException($e)) {            // Grab the HTTP status code from the Exception            $status = $e->getStatusCode();        }        // Return a JSON response with the response array and status code        return response()->json($response, $status);    }    // Default to the parent class' implementation of handler    return parent::render($request, $e);}


In your application you should have app/Http/Middleware/VerifyCsrfToken.php. In that file you can handle how the middleware runs. So you could check if the request is ajax and handle that how you like.

Alternativly, and probably a better solution, would be to edit the exception handler to return json. See app/exceptions/Handler.php, something like the below would be a starting place

public function render($request, Exception $e){    if ($request->ajax() || $request->wantsJson())    {        $json = [            'success' => false,            'error' => [                'code' => $e->getCode(),                'message' => $e->getMessage(),            ],        ];        return response()->json($json, 400);    }    return parent::render($request, $e);}


Building on @Jonathon's handler render function, I would just modify the conditions to exclude ValidationException instances.

// If the request wants JSON + exception is not ValidationExceptionif ($request->wantsJson() && ( ! $exception instanceof ValidationException))

Laravel 5 returns validation errors in JSON already if appropriate.

The full method in App/Exceptions/Handler.php:

/** * 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){    // If the request wants JSON + exception is not ValidationException    if ($request->wantsJson() && ( ! $exception instanceof ValidationException))    {        // Define the response        $response = [            'errors' => 'Sorry, something went wrong.'        ];        // If the 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();        }        // Default response of 400        $status = 400;        // If this exception is an instance of HttpException        if ($this->isHttpException($exception))        {            // Grab the HTTP status code from the Exception            $status = $exception->getCode();        }        // Return a JSON response with the response array and status code        return response()->json($response, $status);    }    return parent::render($request, $exception);}