[精讚] [會員登入]
145

【Discord bot】(ERROR)await self.bot.wait_for() 大坑

今天真的是採到大坑,只找到解決方法,具體原因不明

分享此文連結 //n.sfs.tw/16018

分享連結 【Discord bot】(ERROR)await self.bot.wait_for() 大坑@小編過路君子
(文章歡迎轉載,務必尊重版權註明連結來源)
2022-12-14 04:44:27 最後編修
2022-12-14 03:05:12 By 過路君子
 

哈囉大家好,這裡是對此相當疑惑的小編過路君子

網路上好像都沒有人跟小編遇到一樣的問題,是不是因為連續使用的關係?

 

 

這個問題也是搞得小編一頭霧水,目前小編測試在 2.0.0, 2.0.1, 2.1.0 版本上皆會發生此錯誤。

不知道是跟 bot.event 衝突了還是因為連續使用 wait_for() 這個函數才造成這個問題。

先前情提要一下,小編有自行撰寫 Discord 機器人錯誤響應的程式,如下:

import traceback

@bot.event
async def on_error(event, *args, **kwargs):
    channel = bot.get_channel(000000000000000000)
    await channel.send(traceback.format_exc())

@bot.event
async def on_command_error(ctx, error):
        channel = bot.get_channel(000000000000000000)
        await channel.send('\n'.join(error.args))

所以,等等小編所貼出的錯誤訊息都是由這兩個函數回傳出來的,那我們就開始吧!

 

首先,小編先簡單撰寫一個函數。

此函數會等待使用者在聊天頻道輸入訊息並且將其訊息儲存到變數中。

class replySomething(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.command()
    async def fillblank(self, ctx):
        await ctx.send(content="who?")
        name = (await self.bot.wait_for("message", check=self.bot.check, timeout=300)).content

        await ctx.send(content="age?")
        age = int((await self.bot.wait_for("message", check=self.bot.check, timeout=300)).content)

        await ctx.send(content="where?")
        address = (await self.bot.wait_for("message", check=self.bot.check, timeout=300)).content

 

那此函數是沒有任何的問題的,使用者的輸入皆可以成功被儲存至對應的變數中。

接下來就是問題的所在了,假設小編不小心在撰寫的時候引發一個錯誤(不限種類),例如拿整數去和陣列比較:

if age > [name, address]:
    age += 1

 

然後在 Discord 的聊天欄上去使用此指令,想當然爾,我們會吃到一個錯誤。

而這個錯誤是由 on_command_error 所拋出的,完整訊息如下:

Command raised an exception: TypeError: '>' not supported between instances of 'int' and 'list'

 

接著,我們就保持程式的原樣,不去做任何的修改並再次的執行程式。

這次我們雖然同樣吃了一個錯誤,但是這次卻是由 on_error 所拋出的,完整訊息如下:

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/discord/client.py", line 409, in _run_event
    await coro(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/discord/ext/commands/bot.py", line 1392, in on_message
    await self.process_commands(message)
  File "/usr/local/lib/python3.10/site-packages/discord/ext/commands/bot.py", line 1389, in process_commands
    await self.invoke(ctx) # type: ignore
  File "/usr/local/lib/python3.10/site-packages/discord/ext/commands/bot.py", line 1347, in invoke
    await ctx.command.invoke(ctx)
  File "/usr/local/lib/python3.10/site-packages/discord/ext/commands/core.py", line 978, in invoke
    await self.prepare(ctx)
  File "/usr/local/lib/python3.10/site-packages/discord/ext/commands/core.py", line 882, in prepare
    if not await self.can_run(ctx):
  File "/usr/local/lib/python3.10/site-packages/discord/ext/commands/core.py", line 1227, in can_run
    if not await ctx.bot.can_run(ctx):
  File "/usr/local/lib/python3.10/site-packages/discord/ext/commands/bot.py", line 482, in can_run
    return await discord.utils.async_all(f(ctx) for f in data)
  File "/usr/local/lib/python3.10/site-packages/discord/utils.py", line 660, in async_all
    for elem in gen:
  File "/usr/local/lib/python3.10/site-packages/discord/ext/commands/bot.py", line 482, in <genexpr>
    return await discord.utils.async_all(f(ctx) for f in data)
TypeError: 'Message' object is not callable

出錯的函數本人在這,出錯的位置在最下面那行的 return。

小編在這將其特別擷取出來:

async def can_run(self, ctx: Context[BotT], /, *, call_once: bool = False) -> bool:
    data = self._check_once if call_once else self._checks

    if len(data) == 0:
        return True

    return await discord.utils.async_all(f(ctx) for f in data)

 

真的是非常弔詭的問題,只要 on_command_error 被呼叫之後,第二次之後都會呼叫 on_error 了。

小編花了幾個小時在網路上亂撞,絲毫沒有半點裂縫,好像沒有人遇過跟小編一樣的問題。

 

後來取消用響應的方法的時候,也就是不使用 await wait_for() 之後,就一切正常了?!

所以如果各位剛好遇到相同的問題,而且又剛好看到小編這篇文章,那這邊有兩個臨時解決方案:

  1. 不要使用 await wait_for() 這個函數
  2. 不要使 on_message_error() 被執行到,換句話說,rasie Exception() 之類的函數不可用。

 

 

 

後記

小編其實也有跑到 discord bot 的 github 頁面去查看這個問題是否是已經被回報過了。

很遺憾的,似乎沒有人遇到跟小編一模一樣的問題,看來小編真的是幸運兒,意外的發現一個致命性的錯誤。

END

你可能感興趣的文章

【無料版模】﹝CSS&HTML﹞製作epub電子書版模免費下載&附使用教學 一個專門用來製作epub的簡單CSS檔案,基本上已經可以做出一本還不錯的電子書,讓妳的電子書不在只有預設的字體、樣式

【Wildfly/jBoss】[Linux] 如何從無到有建立Wildfly網頁伺服器 包含一切所需的指令

【Java】[debug]多維泛型的大坑 incompatible types error

【Maven】如何夾帶檔案至Jar內以及其讀取方式 想要讀取一個外部的文字文件?Maven是你的好幫手

【C】(%c, %d)解決讀取字元時的緩衝區殘留 不解決就會莫名其妙地冒出一些莫名其妙的東西

【C++】class練習 — 檢測該字串是否為迴圈 第一次的C++結構式寫法,雖然以後應該會見怪不怪,但畢竟是第一次所以還是想保存下來

我有話要說

>>

限制:留言最高字數1000字。 限制:未登入訪客,每則留言間隔需超過10分鐘,每日最多5則留言。

訪客留言

[無留言]

隨機好文

高捷少女:布拉格體驗㊤ 「可……可以去歐洲玩?而且還有人出錢?太棒囉!」婕兒忍不住歡呼起來,把扳手拋呀拋的,旁邊的客人紛紛轉過來看。「好了啦!」耐耐忍不住害羞起來,輕輕敲了一下婕兒的頭

高捷少女:小穹與果仁巧克力㊤ 阿敏突然輕笑一聲,從櫃臺拿來一個塑膠餐盒,打開給大家看。「這是小穹烤的餅乾,妳們吃吃看就知道她為什麼不想講了。」小穹變得緊張起來。「阿敏,妳怎麼還留著呀?」艾米莉亞、婕兒與耐耐各自拿了一塊,把夾著奶油

高捷少女:購票大作戰(終) 完了。 這下真的完了! 艾米腦內所有的思考中樞,同時發出了淒厲的吶喊。完蛋啦!這下真的被揭穿了啦!! 「那……那是因為……」艾米結結巴巴的說:「因為……

高捷少女:美麗島的守護者① 婕兒跟耐耐嚇得臉色發白。「耐耐,小穹有這方面的愛好喔?」婕兒小聲地說。耐耐默默的拿出筆記本,臉上浮現一層微笑:「這麼大的新聞,要趕快記下來!」

高捷少女:美麗島的守護者⑤  雖然暫時不用怕牠們了,可是一直躲在這裡終究不是辦法,小雅心想。她看看四周,這間更衣室沒有窗戶或後門,她不禁著急起來,不可能一直躲在這裡面,但從門出去只會被群貓圍攻而已。小雅低下頭苦思該怎麼辦,過了不