繁体   English   中英

如何捕获 HTTP 响应错误,然后传递给调用者

[英]How to catch HTTP response error and then pass to the caller

我有一个 API 来将数据更新到数据库。

我正在使用 Fetch API 将数据发送到服务器 API 以将数据存储在数据库中。

如果网络服务器无法将数据更新到数据库,它会返回 500 错误代码和错误消息。

响应 JSON 如下:

{"status":"error","message":"Some wrong when update roster data."}

我的问题是我无法将消息转发给 fetch API 调用者。

这是我获取的 API 源代码:

static async fetchAPI(url,method,getParams,postParams){
  if (getParams){
      const paramsObject = new URLSearchParams(getParams);
      const queryString = paramsObject.toString();  
      url+="?"+queryString;
  }
  url="/rosterWeb"+url;
  console.log("=======================");
  console.log("url="+url);
  console.log("method="+method);
  console.log("getParams="+getParams);
  console.log("postParams="+postParams);
  console.log("=======================");
  return fetch(url,
                {
                    body: JSON.stringify(postParams),
                    headers:{
                        'Content-Type': 'application/json' 
                    },
                    "method":method || 'GET',
                })
          .then(response =>{
            if (response.ok){
              return response.json();                
            } else {
              if (response.status===500){
                response.json()
                .then(json=>{
                  throw new Error(json.message);
                })
              }
            }  
          })
          .catch(error =>{
            console.error('Error:', error);
          });              
                

}

这是我的中间件代码片段:

import Utility from './Utility';
export default class Roster{
  ..............
  .......
  constructor(){
    this.saveToDB=async(data)=>{
        return await Utility.fetchAPI(*saveDataURL*,POST',null,rosterData);
    }
  }
}

这是我的 UI 组件代码片段:

export default function ButtonPanel(){
 ..............................
 
 async function saveDataToDB(){
    
    let roster=new Roster();

    await roster.saveRosterToDB({
       ........................
       ...........................
    })
    .then(result=>{
        console.log("Update Success")
    })
    .catch(error=>{
        console.log("ButtonPanel Exception Caught");
        console.log(error);
    })
    /*
    try{
        let result=await roster.saveRosterToDB({
            month:rosterMonth.getMonth()+1,
            preferredShiftList:rosterData.preferredShiftList,
            rosterList:rosterData.rosterList,
            year:rosterMonth.getFullYear(),
        })
        console.log(result);
    }catch(error){
        console.log("Exception caught.");
        console.log(error.message);
    };
    */
    roster=null;
  }
}

当我执行 Roster.saveRosterToDB 方法时,try-catch 和 then-catch 结构,它也返回以下错误:

`Unhandled Rejection (Error): Some wrong when update roster data.
(anonymous function)
c:/Users/knvb/workspace/rosterWeb_react_node/src/utils/Utility.js:91`

“更新名册数据时出现一些错误”来自响应 JSON。

并且 ButtonPanel.saveDataToDB 将语句“更新成功”打印到控制台。

我试图通过异常将消息从服务器转发到 ButtonPanel。

但是,没有触发异常/错误,我该如何解决?

似乎在 500 状态处理块中缺少return

          fetch(url,
                {
                    body: JSON.stringify(postParams),
                    headers:{
                        'Content-Type': 'application/json' 
                    },
                    "method":method || 'GET',
                })
          .then(response =>{
            if (response.ok){
              return response.json();                
            } else {
              if (response.status===500){
                return response.json() // return was missing here
                .then(json=>{
                  throw new Error(json.message);
                })
              }
            }  
          })
          .catch(error =>{
            console.error('Error:', error);
          });     

上面的代码在 500 状态下将返回 promise。

It'll first get the JSON payload from 500 response and will throw an error with the message from JSON, which will mean that returned promise will become rejected and all catch blocks attached to that promise (including the one with console.error() )将被调用。

主要问题是你正在做的地方throw new Error(json.message)只会导致 promise 从它所在的履行处理程序中被拒绝,但是 promise 没有连接到你有catch的链。 如果你添加了return 例如,改变:

response.json()
    .then(json => {
        throw new Error(json.message);
    })

return response.json()
    .then(json => {
        throw new Error(json.message);
    })

但还有一些其他问题:

  1. fetchAPI是一个async function,所以没有理由在其中使用.then.catch 使用await

  2. 如果response.ok为 false 但response.status不是 500 怎么办? 您的代码失败并最终通过undefinedfetchAPI完成 promise ,但没有说明为什么它没有返回任何内容。 在这种情况下,它也应该引发某种错误。

  3. fetchAPI隐藏所有错误,将它们伪装成值为undefined的结果,因为最后的catch处理程序。 这是一种反模式。 不要在fetchAPI中处理错误,在使用的地方处理它们,以便使用它的代码知道操作是成功还是失败。

以下是我建议您更新fetchAPI的方法:

static async fetchAPI(url, method, getParams, postParams) {
    if (getParams) {
        const paramsObject = new URLSearchParams(getParams);
        const queryString = paramsObject.toString();
        url += "?" + queryString;
    }
    url = "/rosterWeb" + url;
    console.log("=======================");
    console.log("url=" + url);
    console.log("method=" + method);
    console.log("getParams=" + getParams);
    console.log("postParams=" + postParams);
    console.log("=======================");
    const response = await fetch(url, {
        body: JSON.stringify(postParams),
        headers: {
            'Content-Type': 'application/json'
        },
        "method": method || 'GET',
    });
    if (response.status === 500) {
        const error = await response.json();
        throw new Error(error.message);
    } else if (!response.ok) {
        throw new Error(`HTTP error ${response.status}`);
    }
    return response.json();
}

使用时,如果它的promise被满足,就知道是API的数据了。 如果它的 promise 被拒绝,您知道这不是来自 API 的数据,您应该处理/报告错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM