处理 axios 错误和响应 (vue) 仅适用于一个错误。如何通知多个错误?

Handling axios errors and responses (vue) works only with one error. How to notify multiple errors?

我有一个 Vue 应用程序,它与 API(使用 axios 请求)和 return 错误通信。 如果我只得到一个错误,它工作正常,例如当响应是这样的:{"error":"passwords.token"}

当我遇到这样的累积错误时:

{"message":"The given data was invalid.",
 "errors":{
   "password":["The password confirmation does not match."]}
}

这是我的 Vue 组件代码和方法 resetPassword()

methods: {
        resetPassword () {
            this.$vs.loading()

            const payload = {
                userDetails: {
                    email: this.email,
                    password: this.password,
                    password_confirmation: this.password_confirmation,
                    token: this.token
                }
            }

            this.$store.dispatch('auth/resetPassword', payload)
                .then((response) => {
                    this.$vs.loading.close()
                    this.$vs.notify({
                        time: 10000,
                        title: 'Authentication Success',
                        text: response.message.data.message,
                        iconPack: 'feather',
                        icon: 'icon-success-circle',
                        color: 'success'
                    })
                })
                .catch(error => {
                    this.$vs.loading.close()
                    this.$vs.notify({
                        time: 6000,
                        title: 'Authentication Error',
                        text: error.message,
                        iconPack: 'feather',
                        icon: 'icon-alert-circle',
                        color: 'danger'
                    })
                })
        },
    },

不要有不同的密钥,因为一次会出现一个错误,而其他时候会出现两个或三个。例如不要做:
1 个错误:{ 错误:"error message" }
2 个错误:{ 错误:{"error_1":"error message 1"} }
如您所见,那是非常复杂的。只需在其中放置一个语法,然后即使它是一两个左右也可以遵循它。例如你可以让它像

errors: [
   {type: "wrong_user_name_or_password", message: "Wrong user name or password"}
]

然后你可以美化你的通知功能来循环所有的错误并显示它们


无法登录。原因:

  • errors.message
  • 我猜问题是当您遇到多个错误时,您只会看到一条消息 The given data was invalid

    原因如下:

    使用此语法:

    "errors":{
      "password":["The password confirmation does not match."]}
    }
    

    您没有正确使用 error.message,就像您在通知调用中使用的那样:

    this.$vs.notify({
      time: 6000,
      title: 'Authentication Error',
      text: error.message,
      iconPack: 'feather',
      icon: 'icon-alert-circle',
      color: 'danger'
    })
    

    您可以做的是 return 始终出现相同的错误数组,即使您有一个错误或十个错误:

    "errors": [
      {
        type: "password",
        message: "Wrong password"
      },
      {
        type: "user",
        message: "Wrong user"
      },
      // As recommendation, notify only "Authentication error", instead the specific field
      {
        type: "Authentication error",
        message: "Wrong credentials"
      },
    ]
    

    你可以这样通知:

    .catch(error => { // You return errors inside error object
      const errors = error.errors; // and you can get it here
      // const { errors } = error; // alternative syntax
      for (let err on errors) {
        this.$vs.notify({
          time: 6000,
          title: 'Authentication Error', // You can use err.type
          text: err.message,
          iconPack: 'feather',
          icon: 'icon-alert-circle',
          color: 'danger'
        })
      }
    }
    

    替代:

    .catch(error => { // You return errors inside error object
      const errors = error.errors; // and you can get it here
      // const { errors } = error; // alternative syntax
      for (let i = 0; i < errors.length; i++) {
        this.$vs.notify({
          time: 6000,
          title: 'Authentication Error', // You can use errors[i].type
          text: errors[i].message,
          iconPack: 'feather',
          icon: 'icon-alert-circle',
          color: 'danger'
        })
      }
    }
    

    如果您想在错误响应中保留结构,请检查您收到的响应类型并发送通知:

    .catch(err => { // You return errors inside error object
      const { error, errors } = err;
      if (error) { // only one error
        this.$vs.notify({
          time: 6000,
          title: 'Authentication Error',
          text: error.message,
          iconPack: 'feather',
          icon: 'icon-alert-circle',
          color: 'danger'
        })
      } else {
        for (let errorType of errors) { // more than one error
          this.$vs.notify({
            time: 6000,
            title: 'Authentication Error',
            text: errors[errorType][0],
            iconPack: 'feather',
            icon: 'icon-alert-circle',
            color: 'danger'
          })
        }
      }
    }
    

    这种方法不是一个好主意,但如果你想使用它,那很好。

    对于 API 响应,我使用原始 Laravel 的 ResetsPassword.php 中的 sendResetFailedResponse 方法,它看起来像:

    protected function sendResetFailedResponse(Request $request, $response)
        {
            if ($request->wantsJson()) {
                throw ValidationException::withMessages([
                    'email' => [trans($response)],
                ]);
            }
    
            return redirect()->back()
                        ->withInput($request->only('email'))
                        ->withErrors(['email' => trans($response)]);
        }
    

    我已经在我的 API/ResetPasswordController.php 中覆盖了这个方法,如下所示:

    use ResetsPasswords;
    
        protected function sendResetResponse(Request $request, $response)
        {
            $email = $request['email'];
            return response(['message' => $response]);
        }
    
        protected function sendResetFailedResponse(Request $request, $response)
        {
            return response(['error' => $response],422);
        }
    

    和ValidationException.php

    public static function withMessages(array $messages)
    {
        return new static(tap(ValidatorFacade::make([], []), function ($validator) use ($messages) {
            foreach ($messages as $key => $value) {
                foreach (Arr::wrap($value) as $message) {
                    $validator->errors()->add($key, $message);
                }
            }
        }));
    }
    

    API的响应示例(来自 Postman):

    {
        "message": "The given data was invalid.",
        "errors": {
            "token": [
                "The token field is required."
            ],
            "email": [
                "The email field is required."
            ],
            "password": [
                "The password field is required."
            ]
        }
    }