当服务器在 try-catch 块中发送 422 时,axios 无法捕获错误

Posted

技术标签:

【中文标题】当服务器在 try-catch 块中发送 422 时,axios 无法捕获错误【英文标题】:Axios unbale to catch error when server sends 422 in try-catch bloc 【发布时间】:2019-07-19 19:20:36 【问题描述】:

我将axios 用于我的HTTPVue.js。但是当我使用ajax call 时,当server200 成功返回response data 时,一切都会顺利进行。但是当出现错误时,server 不会执行catch bloc。 这是我在 Vue.js 中的 ajax 调用

export default
    data()
        return 
            form:
                email:'',
                password:'',
                password_confirmation:'',
                fname:'',
                lname:'',
                city:''
            ,
            formError:''
        
    ,
    methods:
        //This should be a POST method through axios
        register:async function()
           try
               const res=await axios.post('api/register',this.form);
               console.log("Ba donnees : ",res.data);
           catch(err)
               console.log("Erreeer",err.response);
           
        
    

这是我的注册控制器:

private function validateForm($data)
        return Validator::make($data,
        [
            'fname' => ['required', 'string','min:2' ,'max:255'],
            'lname' => ['required', 'string','min:2' ,'max:255'],
            // 'mname' => ['string','min:2' ,'max:255'],
            'company' => ['string','min:2' ,'max:255'],
            'title' => ['string','min:2' ,'max:255'],
            'phone_number' => ['string','min:13' ,'max:13'],
            'city' => ['required', 'string','min:2' ,'max:100'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8', 'confirmed']
            // 'password_confirm'=>['required','string']
        ]
      )->validate();
    
    //Register
    public function register(Request $request)
        $data=$this->validateForm($request->all());
        $data['password']=Hash::make($data['password']);
        $user=new User($data);
        $user->save();
        return response()->json($user);

    

当一切顺利时,我得到了 try 的预期结果,但在 POST http://localhost:5000/api/register 422 (Unprocessable Entity) 的情况下,正试图在 try 中记录语句。

但是当我进入网络选项卡时,我看到返回的错误JSON 像这样

"message":"给定的数据无效。","errors":"fname":["fname 字段是必需的。"],"lname":["lname 字段是 必填。"],"city":["城市字段为必填项。"],"email":["邮箱 字段为必填项。"],"password":["密码字段为必填项。"]

【问题讨论】:

你使用axios interceptor吗?这可能是您的问题的原因。拦截器捕获您的错误并且不会将其发送回给您 【参考方案1】:

当返回http错误时,axios没有发送异常,你应该使用axios.catch来代替:

axios
  .post('api/register',this.form);
  .then(res =>  console.log("Ba donnees : ",res.data) )
  .catch(err =>  console.log("Erreeer",err.response) );

【讨论】:

我试过你的代码,但没有任何改变 你使用的是then/catch,他使用的是async/await,并且在async/await中没有指定catch块,所有的async函数都在一个try/catch块中。因此你的代码和他的代码是相同的 我尝试更改我的代码并替换为 AzurInspire 提供的代码,但它并没有解决问题 我将您的代码添加到最小的新 Laravel 项目中,并且它正在像它应该的那样开箱即用:github.com/azurinspire/***-54882280 所以我认为它与您的环境有关,而不是您发布的代码本身在这里。【参考方案2】:

您可以使用 validateStatus 属性定义何时应捕获响应,如下所示

axios.post('api/register', 
  validateStatus: function (status) 
    return status < 400; // Reject only if the status code is greater than or equal to 400
  
)

【讨论】:

hmm.. 您在网络选项卡中的响应看起来解析错误,您是否将 Content-Type 设置为 application/json ? 另外,你的初始值是空字符串,什么时候改变?看起来您在用数据填写表单之前调用了注册。 当我提交具有良好值的表单时,post 方法成功执行,但我将字段留空,因为我想捕获错误消息,以便我可以在表单中自定义错误消息跨度> 是的,我已经将 Content-Type 设置为 application/json【参考方案3】:

如果您在某个主 js 文件中全局使用 axios 拦截器,则它不会捕获单独 axios 调用的错误。 为了解决这个问题,你应该做“抛出错误;”就像下面使用 axios 拦截器的地方。

api.interceptors.response.use(     
(response: AxiosResponse) => response,     
(error: AxiosError) =>        
   if (error.response?.status === 401)          
      signOut();       
          
   console.log('throwing error');       
   throw error;     
,   
);

【讨论】:

以上是关于当服务器在 try-catch 块中发送 422 时,axios 无法捕获错误的主要内容,如果未能解决你的问题,请参考以下文章

Nodejs:catch块中的回调函数在try-catch中返回未定义的参数

如何检查线程代码是不是在 try-catch 块中运行

java 在try-catch块中使用if语句不适用于JSoup

try-catch- finally块中, finally块唯一不执行的情况是什么?

std::unique_ptr 取消引用异常未在 try-catch 块中捕获

try-catch()-finally讲解