Unhandled promise rejection - key path incomplete

669 Views Asked by At

I keep getting an error from GCP regarding this, I am using datastore & deploying on GAE. Anyone have any ideas why I am getting this error using javascript promises?

I am using a google action to open on google home, ask for an activation keyphrase if the device has not been registered to an apartment number in datastore already. If it is not registered, it asks for a keyphrase that will associate the unique device id with an apartment number. If the unique id has an apartment associated with it, then is asks what it can help with.

I am not sure why it is saying the key path is incomplete. Also I am new to promises! So any help is greatly appreciated

UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 99): Error: Key path element must not be incomplete: [Activation: ]

With this code?

datastore.get(datastore.key([ACTIVATION, device_id]))
.then(results => {
    let activation = null
    if (results[0] ) {
        activation = results[0]
    }
    return Promise.resolve(activation)
})
.then(activation => {
    console.log(activation)

    let actionMap = new Map();

    actionMap.set('input.welcome', assistant => {
        console.log('input.welcome')
        if (!activation) {
            assistant.ask("Hello! May I have your key phrase?")
        } 
        else {assistant.ask("Welcome back, what can I do for you today?")
        }
    })

    actionMap.set('input.unknown', assistant => {
        console.log('input.unknown')
        if (!activation) {
            assistant.ask("Please provide your activation code")
        } else
        {
            let speech = "OK"
            if (request.body &&
                request.body.result &&
                request.body.result.fulfillment &&
                request.body.result.fulfillment.messages &&
                request.body.result.fulfillment.messages[0] &&
                request.body.result.fulfillment.messages[0].speech) {
                    speech = request.body.result.fulfillment.messages[0].speech
                }
            sendSMSFromUnit(activation.number, request.body.result.resolvedQuery)

            assistant.tell("Got it. ")
        }
})

    actionMap.set('input.keyphrase', assistant => {
        let activationCode = TitleCase([
            assistant.getArgument('Token1'),
            assistant.getArgument('Token2'),
            assistant.getArgument('Token3')
        ].join(" "))
        console.log('activationCode: ' + activationCode)
        if (activation && activation.keyphrase == activationCode) {
            assistant.tell('This device is activated.')
            return
        }

        datastore.get(datastore.key([APARTMENT, activationCode]))
        .then(results => {
            console.log(results)
            if (!results[0]) {
                assistant.ask('Activation unsuccessful.  Can you provide your activation code again?')
                return
            }
            let apartment = results[0]

            datastore.insert({
                key: datastore.key([ACTIVATION, device_id]),
                data: {
                    name: apartment.name,
                    number: apartment.number,
                    keyphrase: activationCode,
                    device_id: device_id
                }
            }).then(() => {
                assistant.ask('Thanks! ')
            })
        })
    })
2

There are 2 best solutions below

0
On

You are getting that error message because you are not catering for when the promise rejects rather than resolves.

In your code where you call '.then', that is when the promise has resolved. But you have no action for when the promise is rejected. Take the following example;

// psuedo promise function which resolves if the data is good and rejects if the data is bad
function myPromiseFunction() {
    return new Promise((resolve,reject) => {
        // do something like make a http call here...
        // if the response is good
        return resolve(response)
        // if the response is not so good
        return reject(error)
    });
}

// using the promise function
myPromiseFunction()
    .then((response) => {
        console.log(response);
    }, (error) => { // <---- you are missing this part
        console.log(error);
    });

or you can write it this way

myPromiseFunction()
    .then((response) => {
        console.log(response);
    })
    .catch((error) => { // <---- you are missing this part
        console.log(error);
    })
0
On

The whole pattern of a promise is

Promise((resolve, reject) => {
  // ...
});

Now how to use it

promiseFunc(...)
   .then((x) => {
     // It get executed well
   })
   .catch((x) => {
     // An error happened
   });

In your code you are missing the .catch part. So if an error get thrown into your promise function you won't catch it and result of a node exception. That's why you have the following warning : Unhandled promise rejection