【问题标题】:How can I manually return or throw a validation error/exception in Laravel?如何在 Laravel 中手动返回或抛出验证错误/异常?
【发布时间】:2018-04-23 11:47:52
【问题描述】:

有一种将 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 的验证以添加像 yhis Validator::extend('foo', function ($attribute, $value, $parameters, $validator) { return $value == 'foo'; }); 这样的复杂处理,然后您可以在规则 'csv_file' => 'required|foo|mimes:csv,txt', 中添加 foo 规则??
  • @Svish 你有你的自定义验证类来抛出验证错误吗?
  • @Svish 我认为 madalinivascu 的 解决方案是您的答案。
  • 您可以在 catch 块中捕获错误消息并执行您的操作。像这样try { //my stuff } catch (Exception $ex) { echo $ex->getMessage(); //Message //$ex->getFile(); //File //$ex->getLine(); //Line }
  • 或者您也可以进行自定义验证并抛出错误,然后像这样在 catch 中处理它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 }

标签: php laravel validation exception error-handling


【解决方案1】:

从 laravel 5.5 开始,您可以使用的 ValidationException class has a static method 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']);

【讨论】:

  • 啊!这 确实 工作,并且还消除了“需要”帮助方法来删除丑陋的消息包的东西。 ? 谢谢!
  • 差不多就是这样,不是一个简单的数组,而是一个多维数组,这个可以工作$error = ValidationException::withMessages([ "one_thing" => ["Validation Message #1"], "another_thing" => ['Validation Message #2'] ]);
  • @JosePalazuelos 由于 Laravel > v5.5 将消息参数转换为带有 Arr::wrap($value) 的数组,因此无需传递二维数组,它可以使用简单的键-值数组。见github.com/laravel/framework/blob/5.5/src/Illuminate/Validation/…
  • 在 6.6 上像魅力一样工作。唯一的缺点是它如何抑制其他验证错误消息。
  • 谢谢!正是我想要的。
【解决方案2】:

Laravel 这个解决方案对我有用:

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

【讨论】:

  • 这也是 Laravel 核心代码库使用的官方方式。
【解决方案3】:

简单地从控制器返回:

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

或:

throw ValidationException::withMessages(['your error message']);

【讨论】:

  • 这个方法有效,但是因为我已经返回(),表单不会使用 {{ old('fieldname') }} 显示以前的值
  • 加上withInput(),就像return back()->withErrors('error')->withInput();
  • 最佳答案(不要忘记withInput()
  • 2021年适用于Laravel 8的修复。也可以传递数组->withErrors(['field' => 'Error message'])
【解决方案4】:

对于 Laravel 5.8:

.

抛出异常最简单的方法是这样的:

throw new \ErrorException('Error found');

【讨论】:

  • 请解释这将如何处理验证错误?
  • 这是相当模糊的。 Laravel 提供了更好的方法来指示错误的类型。
  • 这将引发ErrorException 异常。并且不会被转换成Validation Message。 Insated 它会抛出错误代码 500
【解决方案5】:

您可以尝试自定义消息包

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()]) 不会......?
  • 你需要将$e转成文本,或者使用自定义消息
【解决方案6】:

Laravel 5.5 > 开始,您可以使用

throw_if - 如果给定的布尔表达式计算结果为true,则抛出给定的异常

$foo = true;
throw_if($foo, \Exception::class, 'The foo is true!');

throw_unless - 如果给定的布尔表达式计算结果为false,则抛出给定的异常

$foo = false;
throw_unless($foo);

See here

【讨论】:

    【解决方案7】:

    从 Laravel 8 开始,以下内容在控制器和模型中都有效:

    return back()->withErrors(["email" => "Are you sure the email is correct?"])->withInput();
    

    这将使用户返回到他们之前所在的视图,显示指定字段的指定错误(如果存在),并使用用户刚刚输入的信息重新填充所有字段,允许他们简单地调整不正确的字段,而不是再次填写整个表格。

    另一个功能相似的替代方法是这样做:

    throw ValidationException::withMessages(['email' => 'Are you sure the email is correct?']);
    

    【讨论】:

    • 异常后为什么会有return语句?
    • @AtanasBeychev 很好,已修复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 2012-12-22
    • 2012-06-08
    • 2014-03-21
    • 2018-10-22
    相关资源
    最近更新 更多