即使api失败也要执行`then()`的操作

时间:2019-04-25 08:36:02

标签: javascript reactjs

嗨,我做了一个包装器来获取类似的东西,我正在将该包装器导入组件中,但是在执行该包装器的失败catch()时,但是在组件then()中的功能正在执行任何构想!!

 import { SERVER_URL } from '../configs/serverConfig';

  export default function callApi(api_url: string, method = 'get', data = null) {


    opts = {
      method: method,
      headers: {
        Authorization: 'Basic VFM0NjA2Omsuc3ZpbTg4',
        Accept: 'application/json',
        'Content-Type': 'application/json'
      }
    };
    if (data) {
      opts.data = JSON.stringify(data);
    }
    return fetchWrapper(api_url, opts);
  }



  function fetchWrapper (api_url: string, opts: any){
    let requestParamObj= {};
    if(opts.method.toLocaleLowerCase() === 'get'){
      requestParamObj = {
        method:opts.method
      }
    }
    else if(opts.method.toLocaleLowerCase() === 'post'){
      requestParamObj = {
        method: opts.method,
        headers: opts.headers,
        body: opts.data
      }
    }


    return (
      fetch(api_url, requestParamObj)
        .then((resp) => resp.json())
        .then(response => {
          return response;
        })
        .catch(error => {
          console.log('request failed', error);
          return error;
        })
    )
  }

我在这样的组件中称呼它

    callApi('/someURl', 'GET')
        .then((res) => {
        console.log('this get called even if api fails', res)
    }).catch((err) => {
        //TODO :: error handling at global level
        console.log('Some err', err)
    })
    }

3 个答案:

答案 0 :(得分:2)

这是因为您在包装器中捕获了错误并返回了一个值,因此使用者将获得返回的值而不是错误。

      fetch(api_url, requestParamObj)
        .then((resp) => resp.json())
        .then(response => {
          return response;
        })
        .catch(error => {
          console.log('request failed', error);
          throw error;
        })

如果您将退货错误替换为throw error,则将按预期方式退还消费者捕获物。

PS:即使您希望从网络/ API错误响应中也拒绝诺言,Fetch API也会解决诺言,即使您从API中获得错误状态,也只会触发捕获实际JavaScript错误。您可能想做这样的事情

function handleErrors (response) {
  if (!response.ok) {
    console.log('ERROR: ' + response)
    throw Error(response.statusText)
  }
  return response
}

并使用

.then(handleErrors)

答案 1 :(得分:2)

您有两件事情出错了。

首先,如果由于网络错误导致请求失败,换句话说,请求fetch仅将拒绝返回到catch中-请求永远不会到达您的服务器。如果您收到 any 响应,甚至是HTTP 500,则Promise也会解析为then

第二,与其他答案一样,如果您catch做出承诺,那么会将承诺链转换回成功模式。您需要抛出或返回Promise.reject(value)才能使链条回到故障模式。

您的包装器最好像这样:

return (
  fetch(api_url, requestParamObj)
    .catch(error => Promise.reject(error)) // Handle network error
    .then(response => {
      if (!response.ok) {
        return Promise.reject(response) // Handle error responses HTTP 4XX, 5XX
      } else {
        return response.json() // Return success response HTTP 2XX, 3XX
      }
    })
)

答案 2 :(得分:0)

fetch API会拒绝

  

遇到网络错误,尽管通常这意味着权限问题或类似问题。MDN

在以下示例中,将记录ok

fetch("http://httpstat.us/500")
    .then(function() {
        console.log("ok");
    }).catch(function() {
        console.log("error");
    });

fetch提供了一个ok标志来检查响应是否成功:

fetch("http://httpstat.us/500")
    .then(function(response) {
        if (!response.ok) {
            throw Error(response.statusText);
        }
        return response;
    }).then(function(response) {
        console.log("ok");
    }).catch(function(error) {
        console.log(error);
    });

Source