Як я можу вручну повернути або викинути помилку / виняток перевірки в Laravel?


77

Майте метод, який імпортує CSV-дані до бази даних. Я виконую деякі базові перевірки за допомогою

class CsvImportController extends Controller
{
    public function import(Request $request)
    {   
        $this->validate($request, [
            'csv_file' => 'required|mimes:csv,txt',
        ]);

Але після цього все може піти не так з більш складних причин, далі в кроличу нору, що створює певні винятки. Я не можу написати тут належного матеріалу для перевірки, щоб використовувати його з цим validateметодом, але мені дуже подобається, як працює Laravel, коли перевірка не вдається, і як легко вбудувати помилки (помилки) у перегляд леза тощо, так що ...

Чи існує (бажано чистий) спосіб вручну сказати Laravel, що "я знаю, що зараз я не використовував ваш validateметод, але я б дуже хотів, щоб ви викрили цю помилку тут, як ніби"? Чи є щось, що я можу повернути, виняток, яким я можу обернути речі, чи щось?

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?
}

А як щодо розширення валідації laravel, щоб додати ваше складне лікування, як його, Validator::extend('foo', function ($attribute, $value, $parameters, $validator) { return $value == 'foo'; });тоді ви можете додати правило foo в правила 'csv_file' => 'required|foo|mimes:csv,txt',??
Maraboc

@Svish Чи є у вас власний клас перевірки, на який слід покласти помилку перевірки?
ako

1
@Svish Я думаю , що рішення мадалініваску - це ваша відповідь.
ako

1
Ви можете зловити повідомлення про помилку в блоці catch і робити свої речі. ось такtry { //my stuff } catch (Exception $ex) { echo $ex->getMessage(); //Message //$ex->getFile(); //File //$ex->getLine(); //Line }
Раунак Гупта

1
або ви також можете зробити власну перевірку та викинути помилку, а потім обробити її в улов, як цеtry { $validator = Validator::make($request, ['csv_file' => 'required|mimes:csv,txt']); if ($validator->fails()) { throw new Exception(implode('<br>', $validator->errors()->all()), 999); } } catch (Exception $ex) { if ($ex->getCode() == 999) { //this is a custom error } echo $ex->getMessage(); //Message }
Раунак Гупта

Відповіді:


179

Починаючи з laravel 5.5, у ValidationExceptionкласі є статичний метод,withMessages який ви можете використовувати:

$error = \Illuminate\Validation\ValidationException::withMessages([
   'field_name_1' => ['Validation Message #1'],
   'field_name_2' => ['Validation Message #2'],
]);
throw $error;

Я цього не тестував, але це має спрацювати.

Оновлення

Повідомлення не потрібно обертати масивом. Ви також можете зробити:

use Illuminate\Validation\ValidationException;

throw ValidationException::withMessages(['field_name' => 'This value is incorrect']);

2
Ах! Це справді спрацювало, а також усунуло "потребу" в допоміжному методі, щоб видалити потворні речі із пакетом повідомлень. 😛 Дякую!
Свіш

3
це такий алмос, замість того, щоб бути простим масивом, його багатовимірним масивом, цей працює $error = ValidationException::withMessages([ "one_thing" => ["Validation Message #1"], "another_thing" => ['Validation Message #2'] ]);
Хосе Палазуелос,

@JosePalazuelos Оскільки Laravel> v5.5 передає аргумент повідомлення в масив за допомогою Arr :: wrap ($ value), не потрібно передавати 2D-масив, він буде працювати з простим масивом ключ-значення. Дивіться github.com/laravel/framework/blob/5.5/src/Illuminate/Validation/…
ivanhoe

Працює як шарм на 6.6. Єдиним недоліком є ​​те, як він блокує інші повідомлення про помилки перевірки.
IGP

Дякую! Саме те, що я шукав.
Сайлар

23

Laravel <= 6,2 це рішення для мене спрацювало:

$validator = Validator::make([], []); // Empty data and rules fields
$validator->errors()->add('fieldName', 'This is the error message');
throw new ValidationException($validator);

12

Просто поверніться від контролера:

return back()->withErrors('your error message');

1
Цей метод працює, але оскільки я повернувся назад (), форма не відображатиме попередні значення за допомогою {{old ('fieldname')}}
Кріс

5
додати withInput (), як повернення назад () -> withErrors ('помилка') -> withInput ();
Mantas D

1
Найкраща відповідь (не забувайте проwithInput()
Вахід Амірі


4

Ви можете спробувати власний пакет повідомлень

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()]));
}

Це майже спрацювало. MessageBag, Здається, не як виняток? Тож виклик його з new MessageBag(['exception' => $e])результатами порожнього набору помилок, тоді як new MessageBag(['exception' => $e->getMessage()])не ... does
Svish

вам потрібно перетворити $ e у текст, або скористатися власним повідомленням
madalinivascu
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.