[精讚] [會員登入]
609

【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

你可能感興趣的文章

【JDA/discord bot】如何獲得訊息中的圖片和影片並儲存或轉傳 如何將訊息中的圖片或影片之類的多媒體提取出來之後,再進行相關的處理

【Discord bot】(ERROR)await self.bot.wait_for() 大坑 今天真的是採到大坑,只找到解決方法,具體原因不明

【Python3】11 - 字典(Dictionary)的使用範例 python3的幾個字典使用範例,改寫自他人perl的範例

【Docker&Wildfly】(bitnami/wildfly)如何從零開始創建網頁伺服器 使用他人的 docker image 來架設我們的 wildfly web server

【Vim】解決貼上文字時出現過多空格的問題 換了新系統,有時候就算重裝軟體並且複製了設定檔也還是會出現非常奇怪的現象

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

隨機好文

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

高捷少女:地下城的探險少女③ 過了十分鐘後,前方的天花板滴下一滴水珠,發出「噠」一聲響亮地落在石地上,讓大家嚇一跳。     「什麼嘛,只是水珠而已。」艾米撫著胸口噓了一聲。     忽然間,耐耐的臉色發白起來。「各位,你們看

高捷少女:購票大作戰① 「各位乘客,本班機即將降落,感謝各位乘客的搭乘……」隨著空中小姐的廣播音,那架飛機逐漸降落在地面,裡面的乘客們也紛紛開始整理自己的行李。 那個有著歐美人五官的少女抓緊包包,看著外面的小港機場,臉上緩緩

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

艾米莉亞和高捷戀旅3① 「既然艾米莉亞小姐也來了,就把那個拿出來吧。」美麗島捷運商店的負責人說完,一名工作人員推著一個大箱子進入辦公室。他將箱子打開,將裡面的東西抬出來。艾米張大嘴巴