错误包从 Laravel Livewire Blade 模板中消失

car*_*rse 6 laravel laravel-livewire laravel-fortify

以下 PHP 代码用于捕获来自 Livewire 表单的输入。该表单更新用户的密码,对于眼尖的人来说,您可能会发现它的大部分内容取自 Laravel Fortify 框架。

/**
 * Validate and update the user's password.
 *
 * @param  mixed  $user
 * @param  array  $input
 * @return void
 */
public function update($user, array $input)
{
    try {
        Validator::make($input, [
            'current_password' => ['required', 'string'],
            'password' => $this->passwordRules(),
        ])->after(function ($validator) use ($user, $input) {
            if (! isset($input['current_password']) || ! Hash::check($input['current_password'], $user->password)) {
                $validator->errors()->add('current_password', __('The provided password does not match your current password.'));
            }
        })->validateWithBag('updatePassword');
    } catch (\Illuminate\Validation\ValidationException $e) {
        dd ($e);
    }

    $user->forceFill([
        'password' => Hash::make($input['password']),
    ])->save();
}
Run Code Online (Sandbox Code Playgroud)

如果用户输入无效数据,该dd($e);代码行会向我显示异常对象。此时抛出的异常对象包含一个名为 的错误包updatePassword。这是可以预料的,因为validateWithBag()函数规定应该如此。

到目前为止一切都很好。然而...

如果我尝试捕获 Livewire 模板(或任何 Blade 模板)中的错误,指定的错误包就会消失。为了证明这一点,当检测到错误时,确实<div> 出现以下内容。current_password

@error ('current_password')
    <div>Show error here: {{ $message }}</div>
@enderror
Run Code Online (Sandbox Code Playgroud)

但框架<div>没有显示以下内容:

@error ('current_password', 'updatePassword')
    <div>Show error here: {{ $message }}</div>
@enderror
Run Code Online (Sandbox Code Playgroud)

如果我尝试从刀片模板本身回显$errors对象,则对象类型不再是 type \Illuminate\Validation\ValidationException,而是 type Illuminate\Support\ViewErrorBag

@php dd($errors); @endphp
Run Code Online (Sandbox Code Playgroud)

也许这是可以预料的。但问题是这个$errors对象中包含的唯一错误包是'default'. 错误消息本身是正确的,但它们并不在我期望的包里。

为什么是这样?!

这本身并不是一个大问题,但了解正在发生的事情会很高兴。随着应用程序的扩展,错误消息 ID 的冲突越来越有可能导致意外行为。

Mil*_*tje 2

发生的事情是,Livewire 的作者尚未包含支持多个错误包的逻辑。因此,目前所有包中的所有错误都被收集到一个包中。

作者几乎准备好发布 Livewire 的第 3 版了。让我们希望这个特定功能能够被包含在内......:)

在解决这个问题之前,您可以设置一些可以用作某种错误包指示器的会话变量:

catch (\Illuminate\Validation\ValidationException $e) {
  session()->flash('updatePassword', true);
}
Run Code Online (Sandbox Code Playgroud)