如何在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的验证以添加像yhisValidator::extend('foo', function ($attribute, $value, $parameters, $validator) { return $value == 'foo'; });这样的复杂处理,然后可以在规则中添加foo规则'csv_file' => 'required|foo|mimes:csv,txt',
Maraboc '17

@Svish是否有自定义验证类引发验证错误?
ako 2017年

1
@Svish我认为madalinivascu的解决方案是您的答案。
ako

1
您可以在catch块中捕获错误消息并执行您的工作。这样try { //my stuff } catch (Exception $ex) { echo $ex->getMessage(); //Message //$ex->getFile(); //File //$ex->getLine(); //Line }
Raunak Gupta

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 }
Raunak Gupta

Answers:


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
啊! 这样做确实可行,并且还消除了使用助手方法删除丑陋的messagebag内容的“需求”。😛谢谢!
Svish

3
就像这样的almos,这不是一个简单的数组,而是一个多维数组,这幅作品 $error = ValidationException::withMessages([ "one_thing" => ["Validation Message #1"], "another_thing" => ['Validation Message #2'] ]);
Jose Palazuelos

@JosePalazuelos由于Laravel> v5.5将消息参数转换为带有Arr :: wrap($ value)的数组,因此无需传递2D数组,它将与简单的键值数组一起使用。见github.com/laravel/framework/blob/5.5/src/Illuminate/Validation/…–
ivanhoe

在6.6上像吊饰一样工作。唯一的缺点是它如何抑制其他验证错误消息。
IGP

谢谢!正是我想要的。
锡拉


12

只需从控制器返回:

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

1
此方法有效,但是因为我已经返回(),所以该表单将不会使用{{old('fieldname')}}显示以前的值
Chris

5
添加withInput(),像这样return back()-> withErrors('error')-> withInput();
Mantas D

1
最佳答案(不要忘了withInput()
Vahid Amiri

5

对于Laravel 5.8:

引发异常的最简单方法是这样的:

throw new \ErrorException('Error found');

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()])不会导致错误...🤔–
Svish

您需要将$ e转换为文本,或使用自定义消息
madalinivascu
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.