How can I manually return or throw a validation error/exception in Laravel?
PhpLaravelValidationExceptionError HandlingPhp Problem Overview
Have a method that's importing CSV-data into a Database. I do some basic validation using
class CsvImportController extends Controller
{
public function import(Request $request)
{
$this->validate($request, [
'csv_file' => 'required|mimes:csv,txt',
]);
But after that things can go wrong for more complex reasons, further down the rabbit hole, that throws exceptions of some sort. I can't write proper validation stuff to use with the validate
method here, but, I really like how Laravel works when the validation fails and how easy it is to embed the error(s) into the blade view etc, so...
Is there a (preferably clean) way to manually tell Laravel that "I know I didn't use your validate
method right now, but I'd really like you to expose this error here as if I did"? Is there something I can return, an exception I can wrap things with, or something?
try
{
// Call the rabbit hole of an import method
}
catch(\Exception $e)
{
// Can I return/throw something that to Laravel looks
// like a validation error and acts accordingly here?
}
Php Solutions
Solution 1 - Php
As of laravel 5.5, the ValidationException
class has a static method withMessages
that you can use:
$error = \Illuminate\Validation\ValidationException::withMessages([
'field_name_1' => ['Validation Message #1'],
'field_name_2' => ['Validation Message #2'],
]);
throw $error;
I haven't tested this, but it should work.
Update
The message does not have to be wrapped in an array. You can also do:
use Illuminate\Validation\ValidationException;
throw ValidationException::withMessages(['field_name' => 'This value is incorrect']);
Solution 2 - Php
Laravel <= 6.2 this solution worked for me:
$validator = Validator::make([], []); // Empty data and rules fields
$validator->errors()->add('fieldName', 'This is the error message');
throw new ValidationException($validator);
Solution 3 - Php
Simply return from controller:
return back()->withErrors('your error message');
or:
throw ValidationException::withMessages(['your error message']);
Solution 4 - Php
For Laravel 5.8:
.
The easiest way to throw an exception is like this:
throw new \ErrorException('Error found');
Solution 5 - Php
you can try a custom message bag
try
{
// Call the rabbit hole of an import method
}
catch(\Exception $e)
{
return redirect()->to('dashboard')->withErrors(new \Illuminate\Support\MessageBag(['catch_exception'=>$e->getMessage()]));
}
Solution 6 - Php
As of Laravel 8, the following works in both a controller and a model:
return back()->withErrors(["email" => "Are you sure the email is correct?"])->withInput();
This will return the user to the view they were on previously, displaying the specified error for the specified field (if it exists), and re-populate all the fields with the information the user just entered, allowing them to simply adjust the incorrect field rather than fill out the whole form again.
Another functionally similar alternative would be to do something like this:
throw ValidationException::withMessages(['email' => 'Are you sure the email is correct?']);
Solution 7 - Php
As of on Laravel 5.5 > you can use
throw_if
- throws the given exception if a given boolean expression evaluates to true
$foo = true;
throw_if($foo, \Exception::class, 'The foo is true!');
or
throw_unless
- throws the given exception if a given boolean expression evaluates to false
$foo = false;
throw_unless($foo);