Reputation: 255
im having problems with error handler in my backend laravel api, don't show error message from validation.
routes/api
<?php
Route::group([
'middleware' => 'api',
], function ($router) {
Route::post('access/sign-up', 'AuthenticationController@signUp');
});
AuthenticationController
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\SignUpRequest;
use Illuminate\Http\Request;
use App\User;
class AuthenticationController extends Controller
{
/**
* Create a new AuthenticationController instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth:api', ['except' => ['signUp']]);
}
/**
*
*
* @return \Illuminate\Http\JsonResponse
*/
public function signUp(SignUpRequest $request)
{
//User::create($request->all());
return response()->json([
'data' => 'Usuario creado correctamente.'
]);
}
}
SignUpRequest
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class SignUpRequest 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 [
'email' => 'required|email|unique:users',
'firstName' => 'required',
'password' => 'required',
];
}
}
The thing is that when by postman i send password in blank or not send mail for example it send me to main page insted of sending me a json with all the errors like before. I don't know what to do. I tryed with custom message in SignUpRequest, but that's not the problem, think some kind of redirect in error handler.
Upvotes: 9
Views: 13068
Reputation: 4527
In laravel 9/10
In my case i have a small POST
API
controller that handles a short logic.
I would like to contain it into the class only and not use any FormRequest
rules as it has only 1 method to create a resource and only 1 parameter
this is what i did:
// use Illuminate\Support\Facades\Validator;
// use Illuminate\Http\Exceptions\HttpResponseException;
$validator = Validator::make($request->all(), [
'mac_address' => ['required',new MacArrayCheck]
]);
if ($validator->fails()) {
throw new HttpResponseException(response()->json($validator->errors(), 422));
}
// ... logic here when all validations passes
Read more here Laravel 10 Doc Manual Validation
Upvotes: 0
Reputation: 567
add this method to your formRequest class. It works in laravel 9
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;
class PostRequest extends FormRequest
{
protected function failedValidation(Validator $validator)
{
throw new HttpResponseException(response()->json([
'success' => false,
'message' => 'Validation errors',
'data' => $validator->errors(),
]));
}
/**
* 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()
{
switch ($this->method()) {
case 'GET':
case 'DELETE':{
return [];
}
case 'POST':{
return [
'title' => 'string|unique:posts|required',
'body' => 'required',
'image' => 'string|nullable',
];
}
case 'PUT':{
return [
'title' => 'string|unique:posts|required',
'body' => 'required',
'image' => 'string|nullable',
];
}
}
}
}
Upvotes: 0
Reputation: 41
Update for laravel 8, the first parameter in ValidationException is the Validator class:
protected function failedValidation(Validator $validator)
{
throw new ValidationException($validator, response()->json($validator->errors(), 422));
}
Upvotes: 4
Reputation: 3875
TL;DR Add the following header: Accept: application/json
As mentioned by a few users over here, by default, when a Form Request fails, the application will attempt to redirect the user back to their previous location. That's why you're receiving a webpage instead of a JSON response.
We can also override the "failedValidation" method. But I would recommend setting the following header on the request Accept: application/json
.
Laravel will return the appropriate response based on Accept
header. For application/json
Laravel will return a JSON response with form errors.
Upvotes: 2
Reputation: 598
You need to check just one setting must add Accept Type in header data in Postman
Accept : application/json
that is work in my case...
Upvotes: 19
Reputation: 327
Simply, in your App\Exceptions\Handler, you have to register your custom exception handling in register() method:
public function register() {
$this->renderable( function ( ValidationException $ex, $request ) {
$response = [
'ErrorCode' => 'my_error_code',
'ErrorMessage' => $ex->validator->errors()
];
return response()->json( $response );
} );
}
Upvotes: 1
Reputation: 1
Just add that code to App\Exceptions\Handler
:
public function render($request, Exception $exception)
{
if ($exception instanceof ValidationException) {
return response()->json([
'status' => false,
'error' => [
'type' => 'form',
'code' => 400,
'description' => 'Bad request.',
'detail' => $exception->validator->errors()
]
], 422);
}
return parent::render($request, $exception);
}
Upvotes: -1
Reputation: 322
Using the Form request; If validation fails, a redirect response will be generated to send the user back to their previous location. That's why you are redirecting back to the page instead of the response JSON.
Laravel have one protected method "failedValidation" method. Overwrite this method in your form request class.
protected function failedValidation(\Illuminate\Contracts\Validation\Validator $validator)
{
throw new \Illuminate\Validation\ValidationException(response()->json($validator->errors(), 422));
}
Upvotes: 10
Reputation: 255
Just add that code to SignUpRequest
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;
protected function failedValidation(Validator $validator)
{
throw new HttpResponseException(response()->json($validator->errors(), 422));
}
Upvotes: 17