6
votes

After updating from L5.1 to L5.2, I no longer receive a JSON object as response on a failed FormRequest (i.e. on an AJAX post request).

Usually I would receive a 422 response like:

[
    email: 'E-mail is invalid',
    firstname: 'Firstname must be at least 2 characters'
]

But now I receive a 500 error page:

500 response page

I have ensured that my AJAX calls have application/json as Accept header.

Update

And no, I am not manually catching this exception. I am using the default FormRequest that Laravel provides. As they state in documentation: When using the validate method during an AJAX request, Laravel will not generate a redirect response. Instead, Laravel generates a JSON response containing all of the validation errors. This JSON response will be sent with a 422 HTTP status code.

Like so: php artisan make:request StoreBlogPostRequest (https://laravel.com/docs/5.1/validation#form-request-validation)

3
laravel.com/docs/master/upgrade#upgrade-5.2.0 "The ValidatesRequests trait now throws an instance of Illuminate\Foundation\Validation\ValidationException instead of throwing an instance of Illuminate\Http\Exception\HttpResponseException. This is unlikely to affect your application unless you were manually catching this exception." - ceejayoz
Did you catch the exception taht you throw, in this case HttpResponseException?? - Maraboc
@ceejayoz I am not manually catching this exception. I am using the default FormRequest that Laravel provides. As they state in documentation: When using the validate method during an AJAX request, Laravel will not generate a redirect response. Instead, Laravel generates a JSON response containing all of the validation errors. This JSON response will be sent with a 422 HTTP status code. laravel.com/docs/master/… - FooBar
@Mattias I'd make sure your app/Exceptions/Handler.php matches 5.2's to start with. - ceejayoz
I encountered the same issue. I followed the advice of @ceejayoz, which helped me track the problem down and resolve it. I had a modified app/Exceptions/Handler.php and was overriding the render and renderHttpException functions in Illuminate\Foundation\Exceptions\Handler. For Laravel 5.2, the parent functions have changes to handle ValidatesRequests and HttpResponseException. So, I refactored my code to better depend on the parent functions. All working great again now. - casafred

3 Answers

7
votes

@Mattias!

I've recently had the same issue and I wasted more than 2 hours trying to understand what actually causes this problem. Disabling debugging in .env file causes form validation to display 500 since the FormValidator throws ValidationException (and it is unhandled). The solution for this issue was: Open app\Exceptions\Handler.php

private function handleExceptions($e)
    {
       // Add anywhere in this method the following code
       // It does what the FormValidator does.

        if($e instanceof ValidationException) {

            return redirect()->back()->withErrors($e->validator->getMessageBag()->toArray());
        }

        return response()->view('errors.500', [], 500);
    }
4
votes

To reiterate what the others have said, you more than likely have a modified app/Exceptions/Handler.php in your project where you have some code that is preventing you from seeing the result you'd hoped for.

All exceptions are handled by the App\Exceptions\Handler class. This class contains two methods: report and render.

Double check app/Exceptions/Handler.php and the documentation regarding exception handlers at https://laravel.com/docs/5.2/errors#the-exception-handler to make sure you're handling exceptions as you'd intended.

0
votes

I came against the same problem using Laravel 5.7.

If you read the /storage/logs/laravel-yyyy-mm-dd.log file you will find the error. In my case the error occurred because I forgot a step when linking the StoreLocation request in my Controller:

The error in the log:

[2018-12-13 09:48:09] local.ERROR: Class App\Requests\StoreLocation does not exist

It is perfectly clear that I started writing code without having my coffee first!

The solution:

use App\Http\Requests\StoreLocation;

I added the correct path StoreLocation.php class. After fixing that, everything went back to normal and started sending the 422 response.

PS1: To get the logs, ensure debug mode is on: add APP_DEBUG=true to .env file

PS2: The log file stores the latest entries at the bottom