node.jsaxiospromiseunhandled-promise-rejection

Axios catch crashes code, marked "UnhandledPromiseRejection"


I am trying to handle an axios call failure. I wrote the function and the code:

async function createFunction (url, APIKEY, vendorType) {
  return new Promise((resolve, reject) => {
    const options = {
      method: 'post',
      maxBodyLength: Infinity,
      url: `${url}/vendors/packages`,
      headers: { 
        'x-api-key': `${APIKEY}`
      },
      timeout: 10000,
      data: {
        "contentType": vendorType,
      }
    };
    axios.request(options)
    .then(response =>{
      if (response.status && response.status == 200) {
        resolve(response);
      } else {
        reject(`createFunction Axios call failed with status ${response.status}: ${response.data}`)
      }
    }).catch(err => {
      reject(`createFunction Axios call failed: ${err}`);
    })
  });
}

KbartFunctions.createPackage(host,APIKEY,vendortype)
.then((response) => {
console.log(response);
})

I am getting an error:

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "createFunction Axios call failed: AxiosError: Request failed with status code 400".] {
  code: 'ERR_UNHANDLED_REJECTION'
}

I thought I handled the rejection correctly, but the code crashes anyway. Because the error reads "createFunction Axios call failed:" I know it's in the Catch segment and not the then segment (otherwise it would have said "createFunction Axios call failed with status").

What am I doing wrong?


Solution

  • Couple of problems in your code:

    axios.request already returns a promise, so no need to create a new promise yourself using the Promise constructor. You can just return the promise returned by axios.request(...).

    Your code can be simplified as below:

    function createFunction(url, APIKEY, vendorType) {
      const options = {
        ...
      };
    
      return axios
        .request(options)
        .then(response => {
          if (response.status && response.status == 200) {
            return response;
          } else {
            throw new Error(
              `createFunction Axios call failed with status ${response.status}:${response.data}`
            );
          }
        });
    }
    
    KbartFunctions.createPackage(host, APIKEY, vendortype)
     .then(response => {
       console.log(response);
     })
     .catch(error => { /* handle the error */ });
    
    

    Couple of points to note in the rafactored code:

    If you want to rewrite the createFunction using the async-await syntax, it can be done as shown below:

    async function createFunction(url, APIKEY, vendorType) {
      const options = {
        ...
      };
    
      const response = await axios.request(options);
    
      if (response.status && response.status == 200) {
        return response;
      } else {
        throw new Error(
          `createFunction Axios call failed with status ${response.status}: ${response.data}`
        );
      }
    }