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.
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>