【问题标题】:Unhandled Rejection: Headers cant be set after they are sent未处理的拒绝:标头发送后无法设置
【发布时间】:2023-04-04 13:54:02
【问题描述】:

我正在 Dialogflow 中创建一个聊天机器人。当它抛出未处理的拒绝错误时,我正在尝试将数据添加到数据库中。

这是我的 index.js 文件。

'use strict';

const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
//const {Card, Suggestion} = require('dialogflow-fulfillment');
var admin = require('firebase-admin');
//require("firebase/firestore");
admin.initializeApp(functions.config().firebase);
var firestore = admin.firestore();
//var db = firebase.firestore();
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements

var addRef = firestore.collection('Admission');
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
  const agent = new WebhookClient({ request, response });
  console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
  console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
  console.log("request.body.queryResult.parameters: ", request.body.queryResult.parameters);
  let params = request.body.queryResult.parameters;


  /* function welcome (agent) {
    agent.add(`Welcome to my agent!`);
  } */

  /* function fallback (agent) {
    agent.add(`I didn't understand`);
    agent.add(`I'm sorry, can you try again?`);
  } */

  let responseJson ={};

  function yourFunctionHandler(agent) {
    var docRef = firestore.collection('users');
    name = request.body.queryResult.parameters['myname'];
    coll = request.body.queryResult.parameters['college_name'];
    name = name.charAt(0).toUpperCase() + name.slice(1);
    let balanceresponse = {};
    console.log(name);
    return docRef.add({
      myname: name,
      college: coll
    })
    .then((querySnapshot)=>{
      balanceresponse = {
        "fulfillmentText": 'Sure '+name+', Do you want to know about Admissions, Fees, Graduates and PG, Contact information, Media or Testimonials?'

      }
      console.log('before response.send()');
      response.send(balanceresponse); 
     /*  console.log('before response.send()');
      response.send({
        fulfillmentText:  
             'Sure '+name+', Do you want to know about Admissions, Fees, Graduates and PG, Contact information, Media or Testimonials?'
        //response.json(responseJson);
        }); */
        console.log('after response.send()');
      return 1;
    })
    .catch(error => {
      response.send({
        fulfillmentText:  
          'Something went wrong with the database'
        });
    });
  }

  function AdmissionHandler(agent) {
      console.log("inside Admission Handler");
      let balanceresponse = {};
      let Question = request.body.queryResult.parameters['question'];
      addRef.where("Question", "==", Question)
      .get().then((querySnapshot)=>{
      if (querySnapshot) {
          console.log("Document data:");
          const tips = querySnapshot.docs;
          const tipIndex = Math.floor(Math.random() * tips.length);
          const tip = tips[0];
          balanceresponse = {
            "fulfillmentText": ' Anything else you wanna know?'

         }
         console.log('before response.send()');
         response.send(balanceresponse); 
          /*  response.send({
            fulfillmentText:  
            //firestore.collection(addRef.Answer)+ 
            ' Anything else you wanna know?'
          });  */
          return 1;
      } else {
          // doc.data() will be undefined in this case
          console.log("No such document!");
      }
    return 1;
    })
    .catch(function(error) {
      console.log("Error getting document:", error);
     });


  } 


  // Run the proper function handler based on the matched Dialogflow intent name
  let intentMap = new Map();
 // intentMap.set('Default Welcome Intent', welcome);
 // intentMap.set('Default Fallback Intent', fallback);
  intentMap.set('GetName', yourFunctionHandler);
  intentMap.set('AdmissionCustom', AdmissionHandler);
  agent.handleRequest(intentMap);
});

这是我收到的错误:

我在这里看到的类似问题很少,但没有一个得到回答。有人可以帮忙吗?我已经被困在这里一个多星期了。

【问题讨论】:

  • 您能否更新您的问题以包含函数执行期间的任何日志?
  • 我已经用日志图像更新了问题。请看一下,让我摆脱这个问题。
  • 您能否更新您的问题以显示您如何调用 myFunctionHandler()?
  • 好的。我已经更新了代码。 FunctionHandler 在代码末尾调用。

标签: node.js google-cloud-firestore dialogflow-es


【解决方案1】:

问题在于yourFunctionHandler(agent) 函数异步执行操作,但没有返回 Promise。相反,它什么也不返回,因此处理立即返回而没有发送消息。

因为看起来myDoc.add() 返回了一个 Promise,这很容易通过使 return myDoc.add(...).then(...) 等来处理。它可能看起来像这样:

  function yourFunctionHandler(agent) {
    return docRef.add({
      myname: name,
      college: coll
    })
    .then(()=>{
      response.send({
        fulfillmentText:  
          'Sure '+name+', Do you want to know about Admissions, Fees, Graduates and PG, Contact information, Media or Testimonials?'
      });
      return 1;
    })
    .catch(error => {
      //console.log('érror',e);
      response.send({
        fulfillmentText:  
          'Something went wrong with the database'
        });
    });
  }

此外,您将自己处理响应(通过调用 response.send())和使用 Dialogflow agent.handleRequest(),这将为您创建响应。

您应该使用 Dialogflow 方法来生成回复,例如

agent.add("No such document found.");

或自己使用 JSON 中的值来确定调用哪个处理程序,例如

const intentName = request.body.queryResult.intent.name;
const handler = intentMap[intentName];
handler();

(您可能需要对此进行更改。从您的代码看来,您正在使用我已经反映的 Dialogflow v1,并且意图名称的路径更改为 v2。您还应该检查不存在的处理程序,可能要发送参数等)

【讨论】:

  • 我以前试过这个。我又试了一次,但我仍然收到同样的未处理拒绝错误。
  • 你能用错误的全文更新你的问题吗?
  • 好的。我已经更新了这个问题。请看一看。
  • 根据您在之前问题中的回答之一,我发现问题是 response.send() 在设置标题后发送。所以我尝试了你的解决方案,但它仍然没有给我回复。我将根据您提供的解决方案编辑我的问题。
  • 根据您对问题的补充更新了答案。
猜你喜欢
  • 2017-12-20
  • 1970-01-01
  • 2016-09-02
  • 2018-01-04
  • 2017-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多