[精讚] [會員登入]
460

【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】如何獲得訊息中的圖片和影片並儲存或轉傳 如何將訊息中的圖片或影片之類的多媒體提取出來之後,再進行相關的處理

【JDA/discord bot】取得頻道第一筆或最新(最後一筆)的歷史訊息 在不處理訊息的先後順序下取得相關的歷史訊息

【C++】如何解決TLE,換句話說便是加速cin, cout的執行速度 [ZERO JUDGE](UVa) a159: 11743 - Credit Check 題目練習和副程式練習

【Raspberry Pi/樹梅派】(gcc 10) 如何安裝 gcc & g++ 需要的時間非常久,不愧是gcc的編譯

【MySQL Workbench】如何透過TCP/IP進行SSL連線到遠端MySQL資料庫 通常MySQL伺服器都不是只提供某人連線,而是多人都可以連線進來使用,這時就不能繼續使用localhost的那種寫法

【Wickct】(縮短網址) 如何將網頁掛載到特定路徑下 Wildfly的預設網址又臭又長又不好記,而且會被看到後端的目錄路徑安排,當然能藏就盡量藏起來啦

隨機好文

婕兒──她的青春④ 「投降吧,耐耐!這回合妳將不會再有獲勝的機會了!哈哈哈哈!」 「妳確定?」耐耐臉上泛起一絲微笑,並將手中的牌展示給婕兒看 婕兒的笑容僵住了。恐懼浮現在她的臉。

【英翻中歌詞】(二創歌)東方妖妖夢-人形裁判 ~玩弄人偶的少女 人形裁判 ~ 人の形弄びし少女 很久很久以前,在一個神奇的異地,住著一位少女,十分惹人憐愛 她的皮膚就像陶瓷一樣潔白,眼睛就像藍色寶珠般明亮

【數學】徐氏數學簡明講義(三) 第二章 直線與園 P2.1-17 Q28 28.若X、Y∈R,試求之最小值___ 解: 配方 畫圖 做對稱點 求其直線長度 解

【英翻中歌詞】(二創歌)Reincarnation “Well, hello there. It’s been a while…” 「喔,你好啊!好久不見了...」 Sealed in a sacred shrine… 被封印在神社之中... Ba

【英文作文】如何寫好英文作文 ~英文作文基本架構 從最簡單的英文作文框架開始下手,也就是俗稱的套公式,雖然很笨,但不失一個好辦法。