NodeJS代码执行中的UnhandledPromiseRejectionWarning

时间:2018-08-01 14:44:55

标签: javascript node.js

我当前的nodejs版本是:8.9.1

我正在尝试执行我的代码,但是我总是遇到此错误,试图修复它,但总是有相同的错误:

  

(节点:38)UnhandledPromiseRejectionWarning:未处理的承诺   拒绝(拒绝ID:1):TypeError:无法读取的属性“ body”   未定义(节点:38)[DEP0018] DeprecationWarning:未处理的承诺   不推荐使用。将来,应承诺拒绝   未处理将以非零退出终止Node.js进程   代码。

这是我的代码:

"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
        };
    }
}

非常感谢您的帮助。

谢谢。

2 个答案:

答案 0 :(得分:0)

内部错误告诉您在尝试检索body属性时,对象“ body”的任何属性均未定义。在这种情况下,我的猜测是,当您尝试执行JSON.stringify(context.request.body)时,context.request是未定义的。

您可以在此处详细了解外部错误-https://nodejs.org/api/process.html#process_event_unhandledrejection

答案 1 :(得分:0)

错误告诉您这一行代码:

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

context.request显然是undefined,这意味着context.request.body引发异常。由于context来自呼叫者,因此这意味着呼叫者没有将期望的内容传递给您。 async函数内部的此同步异常导致该函数立即返回被拒绝的Promise。

而且,显然您的呼叫者没有处理拒绝的诺言,因此您会收到有关未处理的拒绝的诺言的警告。

您可以采取多种措施来解决:

  1. 修复调用方,使其始终传递适当的上下文变量。
  2. 修复呼叫者,使其具有被拒绝诺言的处理程序
  3. 修复此功能,以便它捕获异常并像其他拒绝一样处理该异常(返回500状态)。

这是#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
        };
    }
}

此#3修复是很好的防御性编程。它可能会消除对#2的需求,因为此功能可能永远无法拒绝其承诺。

但是,要使您的程序按预期工作,您可能需要弄清楚为什么传入的context不包含您期望的context.request。这可能是问题的真正根源。