'Laravel custom validator returns page instead of json

I made a controller to store tasks, it looks like:

    public function store(StoreTaskRequest $request)
    {
        $validated = $request->validated();

        return response()->json($request);
    }

For the request validation i made a custom validator, that looks like

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreTaskRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'project_id' => 'required',
            'project_name' => 'required',
            'task_id' => 'required',
            'task_name' => 'required',
            'startDate' => 'required',
            'endDate' => 'required',
        ];
    }

    public function messages()
    {
        return [
            'project_id.required' => 'required!',
            'project_name.required' => 'required!',
            'task_id.required' => 'required!',
            'task_name.required' => 'required!',
            'startDate.required' => 'required!',
            'endDate.required' => 'required!',
        ];
    }
}

When i make a post request to that controller with incorrect data it returns an html page but when i post it with the correct data it returns the request as json

By the way i make my post request with: reqbin.com

Post request headers: 
X-Csrf-Token: ....
Content-Type: application/json

Post Params:
{
  "project_name": "Wiza",
  "task_id": 1,
  "task_name": "test 1",
  "startDate": {
    "week": 1,
    "start" : 11,
    "year": 2022
  },
  "endDate": {
     "week": 1,
    "start" : 11,
    "year": 2022
  }
}

Does anyone have any idea why its returning a html page instead of an validation error?

Edit:

api.php is empty web.php

Route::post('api/v1/tasks/', [TaskController::class, 'store']);

//Also tried
Route::resource('api/v1/tasks/', TaskController::class);


Solution 1:[1]

Add this code in your custom validator.

/**
 * Get the error messages for the defined validation rules.*
 * @return array
 */
protected function failedValidation(ValidationValidator $validator)
{
    throw new HttpResponseException(response()->json([
        'message' => implode('', collect($validator->errors())->first()),
        'status' => true
    ], 422));
}

Solution 2:[2]

I have faced the same problem and below mentioned way works for me.

Header Debugging

First You need to verify the list of headers exists in your request. You can do this by following the below code in your controller store method:

 public function store(StoreTaskRequest $request)
    {
       dd($request->headers); //dump your headers exists in $request

       $validated = $request->validated();       
        return response()->json($request);
    }

and that will show you something like:

request headers list in Laravel post request

Solution:

Bestway and clean way to append those headers by using middleware i.e. I've created ForceJsonResponse middleware.

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class ForceJsonResponse
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        $request->headers->set('Accept', 'application/json');
        return $next($request);
    }
}

after that, I've registered that middleware in app/Http/Kernel.php as shown in the screenshot.

register middleware by alias in Laravel

then attach that middleware with that route as shown in the screenshot:

attach middleware alias in route laravel

laravel doc reference for middleware attachement

Worst case scenario

if still, it doesn't work then you can use try catch statement catch Laravel exception in catch statement

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 SecretTimes
Solution 2 khawar Ali