ssilvonen
ssilvonen

Reputation: 33

How to reach Promise reject option in a Google Cloud Function used as a Dialogflow webhook?

I'm building a Dialogflow chatbot that uses a Google Cloud Function as a webhook, with node.js and request-promise-native and without using Firebase or Google Actions. My webhook works fine for fetching and returning the data I want from an external API (Promise resolved), but now I have problems trying to code error handling with Promise reject.

Here is a snippet of code showing what I'm trying to do. With a deliberately wrong URL, the code jumps to the .catch block without ever going to the Promise reject option, and the cloud function log shows the error message "Unhandled rejection".

function searchMyData(agent) {
    return new Promise((resolve, reject) => {
        var myUrl = 'deliberately wrong to trigger rejection';

        // Make the HTTP request with request-promise-native
        // https://www.npmjs.com/package/request-promise

        var options = {
            uri: myUrl,
            headers: {
                'User-Agent': 'Request-Promise-Native'
            },
            json: true
        };

        rpn(options)
            .then((json) => {
                if(json) {
                    // Whole bunch of code for getting the desired data 
                    // and resolving the Promise
                    // This part works
                    var result = agent.add('Here is your data');
                    resolve(result); // Promise resolved
                }
                else { // This block is not run, why?
                    // Reject Promise and return error message to Dialogflow
                    console.log('Promise rejected');
                    var rejectMessage = 'Sorry, an error occurred.';
                    agent.add(rejectMessage);
                    reject(rejectMessage);
                }
            }) // .then end
            .catch((err) => { 
                console.log('In .catch block'); // This is run
                throw new Error('err.message from .catch: '+ err.message); // This is run
            }); // .catch end
    }); // Promise end
} // searchMyData end

I am unclear as to how to structure the code to make it run the Promise rejection when there is an error. The structure used here is what I've seen in tutorials, with the Promise resolved in the if block and rejected in the else block, all within .then, and followed by .catch. But my code never reaches the else block.

Or, alternatively, is it possible to leave out the Promise rejected option altogether, or will it create hidden problems somewhere down the line? All I really want to do in case the webhook does not work is return an error message to the user in Dialogflow (and log the error internally).

Upvotes: 0

Views: 531

Answers (1)

DEVCNN
DEVCNN

Reputation: 622

Read up on Promises. Rejected promises are returned as the second parameter in the then block.

rpn(options)
        .then((json) => {
            if(json) {
                // Whole bunch of code for getting the desired data 
                // and resolving the Promise
                // This part works
                var result = agent.add('Here is your data');
                resolve(result); // Promise resolved
            }
}, error => { // This block will be run on promise rejection

                console.log('Promise rejected');
                var rejectMessage = 'Sorry, an error occurred.';
                agent.add(rejectMessage);
                reject(rejectMessage);
            }
        }) // .then end

Upvotes: 1

Related Questions