Home > front end >  uncaught in promise nested async function promise error handling
uncaught in promise nested async function promise error handling

Time:04-28

I'm trying to implement promises and async/await in my project. I need to use fetch to post some data to server and then do other processes using javascript. but I'm confused on how I should handle the error for nested async/await promises.

the problem is that there's an error "Uncaught (in promise) stop!!" and the string "stop!!" doesn't get added into the div

here's what I tried:

function tunggu(waktu) {
    return new Promise((resolve) => {
    const action = setTimeout(() => {
      const str = `${waktu.toString()} milisecond has passed<br/>`;
      resolve(str);
    }, waktu);
  })
}

const div = document.querySelector('#asd');

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(json => {
    console.log(json);
    
    (async () => {
      div.innerHTML = 'start<br/>';
      const a = await tunggu(2000);
      div.innerHTML  = a;
      throw('stop!!'); // it looks like this line is causing the error
      const b = await tunggu(3000);
      div.innerHTML  = b;
    })();
  })
  .catch(error => {
    console.log('error occurred', error)
    div.innerHTML  = error
  })
<div id="asd"></div>

This (also on jsfiddle) is only a simplified version of my code, in my project the fetch uses the method POST, and the js processes actually have many more process in it so I used throw in it because the error may occur in any place.

CodePudding user response:

there was an error "Uncaught (in promise) stop!!" and the string "stop!!" doesn't get added to the div

You broke the promise chain by introducing a stand-alone async function in the .then() handler (which throws, but has no .catch() of its own, which ultimately causes the error you see).

Instead, make the entire .then() handler async:

function tunggu(waktu) {
  return new Promise((resolve) => {
    setTimeout((() => resolve(`${waktu.toString()} milisecond has passed`)), waktu);
  })
}

const div = document.querySelector('#asd');

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(async (json) => {
    console.log(json);
    
    div.innerHTML = 'start<br/>';
    const a = await tunggu(2000);
    div.innerHTML  = a   '<br/>';
    throw('stop!!');
    const b = await tunggu(3000);
    div.innerHTML  = b;
  })
  .catch(error => {
    console.log('error occurred', error)
    div.innerHTML  = error
  })
<div id="asd"></div>

Alternatively, return the promise from your async IIFE, to keep the promise chain intact:

function tunggu(waktu) {
  return new Promise((resolve) => {
    setTimeout((() => resolve(`${waktu.toString()} milisecond has passed`)), waktu);
  })
}

const div = document.querySelector('#asd');

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(json => {
    console.log(json);
    
    return (async () => {
      div.innerHTML = 'start<br/>';
      const a = await tunggu(2000);
      div.innerHTML  = a   '<br/>'; 
      throw('stop!!');
      const b = await tunggu(3000);
      div.innerHTML  = b;
    })();
  })
  .catch(error => {
    console.log('error occurred', error)
    div.innerHTML  = error
  })
<div id="asd"></div>

  • Related