Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fetch `then()` is executing even if api fails

Hi I have made a wrapper for fetch something like this, I'm importing this wrapper in components but on failure catch() of this wrapper is executing but in the component 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 component 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)
    })
    }
like image 748
shaan Avatar asked Oct 18 '25 05:10

shaan


1 Answers

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)
like image 136
Khaled Osman Avatar answered Oct 20 '25 18:10

Khaled Osman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!