[精讚] [會員登入]
588

【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

你可能感興趣的文章

【MySQL】每個類別中取前三高 一個由多層次所組成的SELECT述句

【C++】使用struct array和一維int array模擬二維int array 主要是因為用sort去排序int array的二維陣列小編懶得研究,於是就研究了一種維持一維陣列但是有二維陣列效果的程式,小編就廢~~

【Discord bot 2.0.1】(discord.ui.View)如何將舊機器人升級至目前最新版本 很多時候升級軟體是為了讓別人覺得你的程式很先進,但這次卻是因為要使用某個新功能

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

【Nexus Repository Manager】(deploy)使他人可以對遠端資料庫做讀寫 使用 Nexus Repository Manager 來讓各個工程師控制自己的 Jar 包,不會有 Github Merge Crashed 問題。

【Linux】網路測速 network speed test 在沒有 GUI 的狀態之下,該如何進行簡單的網路測速呢?

隨機好文

高捷少女:地下城的探險少女② 「等我一下喔,我好像有帶去漬的清潔噴霧。」婕兒翻翻飛揚,拿出噴霧劑給小穹,小穹趕緊對著汙漬噴了噴,紅茶漬果然乾淨了許多。「婕兒,謝謝妳。來,還妳。」小穹感謝地把噴霧還給她,卻發現婕兒盯著打開的飛揚,一

高捷少女:地下城的探險少女(終)  小穹眨眨眼睛,然後說了出來。「其實,從剛剛開始,我就在想了……是在看過這本日記之後。」她拿出日記。「我想……我們尋找寶藏的想法,是不是真的正確的?」「怎麼說呢?」耐耐好奇地問。「這個埋藏寶藏的人,在

高捷少女:美麗島的守護者③ 小雅閉上眼睛,思索在高捷發生的點點滴滴。她心意已決,在高捷的日子的確也有快樂的部分,不過她相信換個方向是更好的決定。有關高捷的所有美好回憶,小雅決定保留在心裡就好,繼續在高捷工作只會讓自己更痛苦而已,

【專輯介紹】蓮台野夜行 ~ Ghostly Field Club,れんだいのやこう 就讓我們隨著音樂跟著秘封俱樂部一起探詢那不可思議的未知和神秘,若處理不好,說不定會招來奇怪的靈呦(・ω<)☆

【阿瑞斯病毒】(影片示範)快速採滿100塊的鐵礦一點都不難! 感覺超像廢文的一篇?連小編自己都覺得寫得很差勁,還是上一篇擊殺棘刺豬教學的那篇寫得比較好!