Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify validation exception formatting. #20173

Merged
merged 6 commits into from
Jul 19, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Unify validation exception formatting.
This unifies all validation error formatting into the exception handler
and out of Form Request. “Don’t Flash” is typically a global concept
that always applies to a list of fields for all pages in the
applications, so seemed to make sense to specify in one place instead
of each form.

Total control of the Form Request error response can still be gained by
overriding failedValidation and throwing a HttpResponseException with
whatever response you want.
  • Loading branch information
taylorotwell committed Jul 19, 2017
commit 0590a03018a21b5573131d87fbfa584c4a4fbc53
27 changes: 19 additions & 8 deletions src/Illuminate/Foundation/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ class Handler implements ExceptionHandlerContract
\Illuminate\Validation\ValidationException::class,
];

/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];

/**
* Create a new exception handler instance.
*
Expand Down Expand Up @@ -222,13 +232,14 @@ protected function convertValidationExceptionToResponse(ValidationException $e,
*/
protected function invalid($request, ValidationException $exception)
{
return redirect()->back()->withInput($request->except([
'password',
'password_confirmation',
]))->withErrors(
$exception->validator->errors()->messages(),
$exception->errorBag
);
$url = $exception->redirectTo ?? url()->previous();

return redirect($url)
->withInput($request->except($this->dontFlash))
->withErrors(
$exception->validator->errors()->messages(),
$exception->errorBag
);
}

/**
Expand All @@ -242,7 +253,7 @@ protected function invalidJson($request, ValidationException $exception)
{
return response()->json([
'message' => $exception->getMessage(),
'errors' => $exception->validator->errors()->messages(),
'errors' => $exception->errors()
], 422);
}

Expand Down
55 changes: 3 additions & 52 deletions src/Illuminate/Foundation/Http/FormRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,6 @@ class FormRequest extends Request implements ValidatesWhenResolved
*/
protected $errorBag = 'default';

/**
* The input keys that should not be flashed on redirect.
*
* @var array
*/
protected $dontFlash = ['password', 'password_confirmation'];

/**
* Get the validator instance for the request.
*
Expand Down Expand Up @@ -122,51 +115,9 @@ protected function validationData()
*/
protected function failedValidation(Validator $validator)
{
throw new ValidationException($validator, $this->response(
$this->formatErrors($validator)
));
}

/**
* Get the proper failed validation response for the request.
*
* @param array $errors
* @return \Symfony\Component\HttpFoundation\Response
*/
public function response(array $errors)
{
if ($this->expectsJson()) {
return $this->jsonResponse($errors);
}

return $this->redirector->to($this->getRedirectUrl())
->withInput($this->except($this->dontFlash))
->withErrors($errors, $this->errorBag);
}

/**
* Get the proper failed validation JSON response for the request.
*
* @param array $errors
* @return \Illuminate\Http\JsonResponse
*/
public function jsonResponse(array $errors)
{
return new JsonResponse([
'message' => 'The given data was invalid.',
'errors' => $errors,
], 422);
}

/**
* Format the errors from the given Validator instance.
*
* @param \Illuminate\Contracts\Validation\Validator $validator
* @return array
*/
protected function formatErrors(Validator $validator)
{
return $validator->getMessageBag()->toArray();
throw (new ValidationException($validator))
->errorBag($this->errorBag)
->redirectTo($this->getRedirectUrl());
}

/**
Expand Down
43 changes: 43 additions & 0 deletions src/Illuminate/Validation/ValidationException.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ class ValidationException extends Exception
*/
public $errorBag;

/**
* The path the client should be redirected to.
*
* @var string
*/
public $redirectTo;

/**
* Create a new exception instance.
*
Expand All @@ -44,6 +51,42 @@ public function __construct($validator, $response = null, $errorBag = 'default')
$this->validator = $validator;
}

/**
* Get all of the validation error messages.
*
* @return array
*/
public function errors()
{
return $this->validator->errors()->messages();
}

/**
* Set the error bag on the exception.
*
* @param string $errorBag
* @return $this
*/
public function errorBag($errorBag)
{
$this->errorBag = $errorBag;

return $this;
}

/**
* Set the URL to redirect to on a validation error.
*
* @param string $url
* @return string
*/
public function redirectTo($url)
{
$this->redirectTo = $url;

return $this;
}

/**
* Get the underlying response instance.
*
Expand Down