【问题标题】:Bot Framework V4 - TypeError: Cannot perform 'get' on a proxy that has been revokedBot Framework V4 - TypeError:无法在已撤销的代理上执行“获取”
【发布时间】:2018-10-24 13:00:49
【问题描述】:

我正在尝试对存储用户知识文章的数据库进行休息查询,并根据用户搜索的内容返回一组结果。每当我尝试搜索时,我都会得到:

"TypeError: 无法在已撤销的代理上执行 'get'"

我已尝试将其添加到 async 中,如图所示,但我仍然不断收到相同的错误。知道我做错了什么吗?

const Response = async (turnContext) => {
    if (turnContext.activity.value.choice === 'feedbackProvider') {
        try {
            const feedbackBody = turnContext.activity.value.feedbackBody;
            const feedbackEmail = turnContext.activity.value.feedbackEmail;
            storage.write(feedbackBody, feedbackEmail);
            await turnContext.sendActivity(`Feedback Sent`);
        } catch (err) {
            console.log('fetch failed', err);
        }
    } else if (turnContext.activity.value.choice === 'issueRaiser') {
        try {
            const bugTitle = turnContext.activity.value.issueTitle;
            const bugDesc = turnContext.activity.value.issueDescription;
            const bugEmail = turnContext.activity.value.issueEmail;
            const request = require('request');
            request({
                method: 'Post',
                uri: `<uri>issues?title=${ bugTitle }&description=${ bugDesc } ${ bugEmail }&labels=bug`,
                json: true,
                headers: {
                    'Private-Token': '<token>'
                }
            });
            turnContext.sendActivity(`Issue Raised`);
        } catch (err) {
            console.log('fetch failed', err);
        }
    } else if (turnContext.activity.value.choice === 'knowledgeBaseSearch') {
        try {
            const knowledgeBaseTopic = turnContext.activity.value.knowledgeBaseTopic;
            request({
                url: process.env.SN_KB_URL + knowledgeBaseTopic,
                json: true,
                auth: {
                    'username': process.env.Ticket_User,
                    'password': process.env.Ticket_Key
                }
            }, async (error, response, body) => {
                try {
                    var stuff = [];
                    for (var i = 0, len = body.result.length; i < len; i++) {
                        stuff.push(
                            CardFactory.heroCard(body.result[i].short_description, ['imageUrl1'], [`${ process.env.SN_KB_Resp_URl }${ body.result[i].number }`])

                        );
                    }
                    let messageWithCarouselOfCards = MessageFactory.carousel(stuff);
                    await turnContext.sendActivity(messageWithCarouselOfCards);
                } catch (err) {
                    console.log(error);
                }
            });
        } catch (err) {
            console.log('fetch failed', err);
        }
    }
};

完整的错误信息:

TypeError: Cannot perform 'get' on a proxy that has been revoked
cardMiddleware.js:35
    at Request.request [as _callback] (c:\Bots\sdk4-2\skills\cardMiddleware.js:35:45)
    at Request.self.callback (c:\Bots\sdk4-2\node_modules\request\request.js:186:22)
    at emitTwo (events.js:126:13)
    at Request.emit (events.js:214:7)
    at Request.<anonymous> (c:\Bots\sdk4-2\node_modules\request\request.js:1163:10)
    at emitOne (events.js:116:13)
    at Request.emit (events.js:211:7)
    at IncomingMessage.<anonymous> (c:\Bots\sdk4-2\node_modules\request\request.js:1085:12)
    at Object.onceWrapper (events.js:313:30)
    at emitNone (events.js:111:20)

从我在论坛上的帖子中得知,我正在使用一个不支持 Promises 的请求模块,我认为这导致了我的错误。我现在已经开始使用 Axios 来处理我的请求,如下所示;

try {
    return await axios.get(process.env.SN_KB_URL + knowledgeBaseTopic, {
        headers: {
          auth: {
          username: process.env.Ticket_User,
          password: process.env.Ticket_Key
        }
      }
    })
  }

但是现在当我运行请求时,我收到 401“未经授权”错误,我不确定我的请求有什么问题。

【问题讨论】:

  • 考虑到您只是在发帖而不是获取,并且您的代码没有提及任何代理,这尤其令人好奇。你能找出是哪一行引发了错误吗?
  • 嗨@Mark!我今天也遇到了同样的错误,我将寻找可以提供帮助的人。等我有解决方案后,我会发布!
  • 马克,你能把剩下的错误贴出来吗?
  • @MarkWeir:在寻找解决方案时,myget 提要上每日发布的 botbuilder 软件包似乎已经解决了这个问题。您可以使用 myget 包 4.1.5 进行测试构建吗? Myget daily JS build
  • @JJ_Wailes 我已经更新了软件包,但仍然遇到同样的错误。我将尝试使用不同的请求模块,因为我不相信我当前的请求模块支持承诺 (valentinog.com/blog/http-requests-node-js-async-await)

标签: javascript botframework


【解决方案1】:

出现这个问题是因为我使用的请求模块不支持 Promise。将我的请求模块更改为支持承诺的模块(我通过使用this article 发现)解决了这个问题。

【讨论】:

  • 链接失效
【解决方案2】:

我的答案是仔细检查我没有错过任何可能需要的 await 用法。原来我在没有await 的情况下调用了this.dialog.run(context, this.dialogState);,这引发了同样的错误。我在this Github issue找到了答案

【讨论】:

    【解决方案3】:

    我将把它放在这里只是因为它是搜索时弹出的第一个结果,尽管它与这个问题没有直接关系。

    有一个非常简单的方法可以使用setTimeout() 并避免此错误:

    await new Promise(resolve => setTimeout(() => resolve(
        turnContext.sendActivity('I was sent 5 seconds later')
    ), 5000));
    

    【讨论】:

      【解决方案4】:

      我花了很多时间来解决这个问题。正如其他评论者所指出的,问题在于 Lex 运行时不是基于承诺的,因此您不能等待请求,这会导致代理被撤销。

      这是我的解决方案:

      async callLex(context) {
          const params = {
              botAlias: 'prod',
              botName: 'botName',
              userId: context.activity.from.id,
              contentType: 'text/plain; charset=utf-8',
              accept: 'text/plain; charset=utf-8',
              inputStream: context.activity.text.trim()
          }
          let request = lexruntime.postContent(params)
          await request.promise().then(
              async response => {
                  console.log(response)
                  console.log('Success!')
                  await context.sendActivity(response.message)          
              },
              err => {
                  console.log(err)
                  console.log('Error!')
              })
      }
      

      我没有像“lexruntime.postContent(params, callback func)”这样直接调用请求,而是排除了回调函数,并利用 AWS.Request 的“promise”属性将请求作为可以让我使用的承诺发送“等待”并保持代理打开。 See documentation here.

      【讨论】:

        【解决方案5】:

        在我的场景中,我们试图将文件从任务模块(团队的模式弹出窗口)上传到机器人,作为响应,机器人会首先确认附件正在上传。此活动将关闭任务模块(因为机器人必须在 10 秒内回复,否则团队将重新发送请求)。现在,当附件上传时,我们想用上传的附件列表更新之前发送的自适应卡片。我们使用机器人框架的主动消息传递功能实现了这一点。

        const conversationReference = TurnContext.getConversationReference(activity);
        Promise.all(listOfPromises).then(() => {
            await botAdapter.continueConversation(conversationReference, async turnContext => {
                await turnContext.sendActivity('All attachments uploaded!');
            });
        }
        

        文档:https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-howto-proactive-message?view=azure-bot-service-4.0&tabs=javascript

        【讨论】:

          【解决方案6】:

          在任何 aync 函数中检查需要 await 的行。我希望 azure 能具体指出哪个文件或行,但直到我查看了我的所有函数后我才弄清楚。

          好的,这确实是一个非常神秘的错误消息,正如 github 线程 here 所建议的那样。

          但是我发现我在这个区块里没有awaiting:

              this.onMessage(async (context, next) => {.
                const didBotWelcomedUser = await this.welcomedUserProperty.get(
                  context,
                  "false"
                );  
          
                if (didBotWelcomedUser === false) {
                  // first time user is in chat
                  await this.sendWelcomeMessage(context); `<-------- await here was missing`
                } else {
                  await this.sendSuggestedAction(context); `<-------- await here was missing`
                }
          
          
          
                await next();
              });
          
              this.onMembersAdded(async (context, next) => {
          
          
                await this.sendWelcomeMessage(context);
                await next();
              });
            }

          我认为await.next() 就足够了。我们都必须以某种方式学习这一点......希望你能解决你的问题。

          【讨论】:

            猜你喜欢
            • 2020-09-27
            • 2023-03-25
            • 1970-01-01
            • 2021-02-14
            • 2021-02-01
            • 2021-10-25
            • 2020-12-17
            • 2022-08-11
            • 2021-04-26
            相关资源
            最近更新 更多