简体   繁体   中英

Throw Error with loop of await function

I'm struggling with a loop of async await function. I'm creating an API which POST a request to another API. I have to make a loop because users could insert many items at once in the database.

The API that I call rejects Parallel executions so I can't use Promise.all :/

In order to implement that service I made a function to insert one object :

const addValue = async (ID:number, cookie: string) => {
    try {
        const addValueBody = await addValueQuery(ID:number)
        const header = { 'cookie': cookie, 'content-type': 'application/json' }
        const fetchResult = fetch('http://api-to-call.xyz', { method: `POST`, headers: header, body: addValueBody })
        const response = await fetchResult
        const jsonData = await response.json()
        return jsonData
     } catch (e) {
        throw Error(e.message)
    }
}

And a function which will execute addValue inside a for loop :

const addMulti = async (values: any, cookie: string) => {
    for (const item of values) {
           await addValue(item.ID, cookie)
    }
}

The problem is that when I call addMulti and if there is an Error I have a UnhandledPromiseRejectionWarning .

Also I tried to put de for ... in or await addValue inside a try catch but it doesn't catch the Error(s)

Hence, I have 2 questions :

How can I throw en Error if it occurs during the execution of the loop ? Is it possible to break the loop if there is an error ?

Thanks for your help :)

How can I throw en Error if it occurs during the execution of the loop ? Is it possible to break the loop if there is an error ?

Your code does that already, by await ing addValue . If addValue throws an error, since addMulti doesn't catch , it terminates addMulti as well.

The problem is that when I call addMulti and if there is an Error I have a UnhandledPromiseRejectionWarning.

The code you've shown is correct¹, the problem is that it appears you have no error handling on the call to addMulti . That code must either:

  • Handle errors from it (via try / catch in an async function if you don't want to allow it to propagate, or via the catch method if using the promise directly), or
  • Propagate the error to something that will handle it (by not catching it in an async function, or by returning the promise in a non- async function)

So for instance, if the call to addMulti is in a non- async function and if nothing calling that function will handle errors, you need to handle it at that stage:

addMulti(/*...*/)
    .catch(error => {
        // ...handle/report the error
    });

If it's in an async function but nothing handles that async function's errors, then:

try {
    await addMulti(/*...*/);
} catch (e) {
     // ...handle/report the error
}

¹ ...other than it seems odd to catch e and then do throw Error(e.message) ; just let the error propagate.

When you get UnhandledPromiseRejection working with async functions, it almost surely means that you didn't catch the thrown error. In your case you could just wrap the whole loop in try{...} catch{...} block:

const addMulti = async (values: any, cookie: string) => {
    try {
        for (const item of values) {
           await addValue(item.ID, cookie)
       }
    } catch(e) {
        console.log('Error occured in async function')
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM