1
votes

My current nodejs version is: 8.9.1

I'm trying to execute my code but i'm always having this error, tried to fix it but have always the same error :

(node:38) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot read property 'body' of undefined (node:38) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Here it is my code:

"use strict";
const rp = require("request-promise-native");
module.exports = async function (context) {
    const stringBody = JSON.stringify(context.request.body);
    const body = JSON.parse(stringBody);
    const location = body.location;
    if (!location) {
        return {
            status: 400,
            body: {
                text: "You must provide a location."
            }
        };
    }
    try {
        const response = await rp(`https://query.yahooapis.com/v1/public/yql?q=select item.condition from weather.forecast where woeid in (select woeid from geo.places(1) where text="${location}") and u="c"&format=json`);
        const condition = JSON.parse(response).query.results.channel.item.condition;
        const text = condition.text;
        const temperature = condition.temp;
        return {
            status: 200,
            body: {
                text: `It is ${temperature} celsius degrees in ${location} and ${text}`
            },
            headers: {
                "Content-Type": "application/json"
            }
        };
    } catch (e) {
        console.error(e);
        return {
            status: 500,
            body: e
        };
    }
}

I will really appreciate your help.

Thank you.

2

2 Answers

0
votes

The inner error is telling you that whatever object "body" is a property of is undefined at the time you're trying to retrieve the body property. In this scenario, my guess is that when you try to do JSON.stringify(context.request.body), context.request is undefined.

You can read more about the outer error here - https://nodejs.org/api/process.html#process_event_unhandledrejection

0
votes

The error is telling you that on this line of code:

const stringBody = JSON.stringify(context.request.body);

context.request is apparently undefined which means that context.request.body throws an exception. Since context is coming from the caller, this means that the caller is not passing you what you expect. This synchronous exception inside an async function causes that function to immediately return a rejected promise.

And, apparently your caller is not handling a rejected promise so you then get the warning about an unhandled rejected promise.

There are multiple things you can do to fix:

  1. Fix the caller so it is always passing an appropriate context variable.
  2. Fix the caller so it has a handler for a rejected promise
  3. Fix this function so that it catches the exception and handles it like your other rejections (by returning the 500 status).

Here's the fix for #3:

"use strict";
const rp = require("request-promise-native");
module.exports = async function (context) {
    try {
        const stringBody = JSON.stringify(context.request.body);
        const body = JSON.parse(stringBody);
        const location = body.location;
        if (!location) {
            return {
                status: 400,
                body: {
                    text: "You must provide a location."
                }
            };
        }
        const response = await rp(`https://query.yahooapis.com/v1/public/yql?q=select item.condition from weather.forecast where woeid in (select woeid from geo.places(1) where text="${location}") and u="c"&format=json`);
        const condition = JSON.parse(response).query.results.channel.item.condition;
        const text = condition.text;
        const temperature = condition.temp;
        return {
            status: 200,
            body: {
                text: `It is ${temperature} celsius degrees in ${location} and ${text}`
            },
            headers: {
                "Content-Type": "application/json"
            }
        };
    } catch (e) {
        console.error(e);
        return {
            status: 500,
            body: e
        };
    }
}

This fix for #3 is good defensive programming. It probably removes the need for #2 because this function probably can't ever reject its promise.

But, to make your program work as expected, you probably need to figure out why the context being passed in does not contain context.request like you expect. That's probably the real source of the issue.