最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - fetch `then()` is executing even if api fails - Stack Overflow

programmeradmin1浏览0评论

Hi I have made a wrapper for fetch something like this, I'm importing this wrapper in ponents but on failure catch() of this wrapper is executing but in the ponent then() function is executing any idea!!

 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;
        })
    )
  }

I'm calling this in a ponent something like this

    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)
    })
    }

Hi I have made a wrapper for fetch something like this, I'm importing this wrapper in ponents but on failure catch() of this wrapper is executing but in the ponent then() function is executing any idea!!

 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;
        })
    )
  }

I'm calling this in a ponent something like this

    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)
    })
    }
Share Improve this question asked Apr 25, 2019 at 8:36 shaanshaan 5246 silver badges26 bronze badges 1
  • What do you have in your res var when it's fail, it can help a lot to know what happen ! – ekans Commented Apr 25, 2019 at 8:40
Add a ment  | 

3 Answers 3

Reset to default 5

This is because you're catching the error in the wrapper and returning a value, so the consumer will get the returned value instead of the error.

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

if you replace return error with throw error the consumer catch will be returned as expected.

PS: Fetch API will resolve the promise even if you get an error status from the API, it will only trigger the catch on actual JavaScript errors, if you want the promise to be rejected on network/API error responses aswell. you might want to do something like this

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

and use

.then(handleErrors)

You have two things going wrong.

Firstly, the promise fetch returns only rejects into catch if the request fails due to a network error, or in other words - the request never gets to your server. If you get any response, even a HTTP 500, then the promise resolves into then.

Secondly, like the other answer mentions, if you catch a promise then that converts the promise chain back into a success mode. You need to throw, or return Promise.reject(value) to kick the chain back into a failure mode.

Your wrapper would better look like:

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
      }
    })
)

fetch API rejects the promise if

network error is encountered, although this usually means permissions issues or similar.MDN

In the following example ok will be logged:

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

fetch provides an ok flag to check that the response is successful:

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

发布评论

评论列表(0)

  1. 暂无评论