简体   繁体   中英

How to handle reject promise error in outer try catch with inner Promise.all?

When an error/rejection occurs in detectingDog or detectingDog , the error is successfully handled by the .catch(error of the Promise.all() but I want the error to be directly handled by the catch (err) of the try structure.

How can I do this?

PS: I have already tried to get rid of the .catch(error but then the Promise.all() hangs forever

try {
        function detectingDog(bufferedData) {
            return new Promise((resolve, reject) => {
                package.detectDog(bufferedData, function(error, data) {
                    if (error) {
                        reject(error);
                    } else {
                        return resolve(data);
                    }
                });
            });
        }                

        function detectingCat(bufferedData) {
            return new Promise((resolve, reject) => {
                package.detectCat(bufferedData, function(error, data) {
                    if (error) {
                        reject(error); 
                    } else {
                        return resolve(data); 
                    }
                });
            });
        }                

        Promise.all([
            detectingDog(param1),
            detectingCat(param2)
        ]).then(responseData => { 
            callback(undefined, responseData);                                         
        }).catch(error => { 
            // (1) I need to pass the error to the outer structure where error handling is done
        });
    } catch (err) {                
        console.log(err); 
           // handing of the inner error (2) here
        callback(err);                 
    }

Thanks!

...but I want the error to be directly handled by the catch (err) of the try structure.

You can't do that in a non- async function, because control has already left the try / catch by the time that rejection occurs, which is after whatever function this code is in (if any) has returned.

In an async function, you can use await on a promise, which will make a rejection throw , so it would go to your try / catch . So you could do the following, but keep reading because it's fairly odd:

// In an `async` function
try {
    function detectingDog(bufferedData) {
        return new Promise((resolve, reject) => {
            package.detectDog(bufferedData, function(error, data) {
                if (error) {
                    reject(error);
                } else {
                    return resolve(data);
                }
            });
        });
    }                

    function detectingCat(bufferedData) {
        return new Promise((resolve, reject) => {
            package.detectCat(bufferedData, function(error, data) {
                if (error) {
                    reject(error); 
                } else {
                    return resolve(data); 
                }
            });
        });
    }                

    const responseData = await Promise.all([
        detectingDog(param1),
        detectingCat(param2)
    ]);
    callback(responseData);
} catch (err) {                
    console.log(err); 
    callback(err);                 
}

...but it doesn't make a lot of sense to go to the trouble of converting callback APIs to promises if you're just going to provide a callback-based API to your caller. Just return a promise. That makes the whole try / catch disappear:

// No need for these to be nested
function detectingDog(bufferedData) {
    return new Promise((resolve, reject) => {
        package.detectDog(bufferedData, function(error, data) {
            if (error) {
                reject(error);
            } else {
                resolve(data); // No need for `return`
            }
        });
    });
}                

function detectingCat(bufferedData) {
    return new Promise((resolve, reject) => {
        package.detectCat(bufferedData, function(error, data) {
            if (error) {
                reject(error); 
            } else {
                resolve(data); 
            }
        });
    });
}                

function example(param1, param2) {
    return Promise.all([
        detectingDog(param1),
        detectingCat(param2)
    ]);
}

You have two options here.

If you really need the try/catch block you will need to run your code in an async function, leveraging the fact that awaiting a rejected Promise will throw an error in this context:

(async function () { // you might not need the immediately invoking function wrapper depending on your context
    try {
        function one(bufferedData) {
            // return a promise
        }                

        function two(bufferedData) {
            // return a Promise
        }                

        const responseData = await Promise.all([
            one(param1),
            two(param2)
        ])
        callback(undefined, responseData)
    } catch (err) {                
        console.log(err);
        // handing of the inner error (2) here
        callback(err)              
    }
})()

Alternatively, you can also just handle the error in the catch block of your Promise chain:

function one(bufferedData) {
    // return a promise
}                

function two(bufferedData) {
    // return a Promise
}                

Promise.all([
    one(param1),
    two(param2)
])
.then((responseData) => {
    callback(undefined, responseData)
})
.catch((err) => {    
    console.log(err);
    // handing of the inner error (2) here
    callback(err)              
})

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