Discord.py报错ValueError: <class 'str'> is not a valid ChannelType求助
问题:Discord.py天气斜杠命令触发ChannelType ValueError错误
开发Discord.py天气查询斜杠命令时,触发了<class 'str'> is not a valid ChannelType的ValueError错误,附上完整报错回溯与代码片段,多次修改无法定位问题,请求排查解决。
报错信息
> 忽略命令weather中的异常: > 回溯(最近的调用最后): 文件 "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/enums.py", 第168行, 在 __call__中 > return cls._enum_value_map_[value] > KeyError: <class 'str'> > 在处理上述异常期间,发生了另一个异常: 回溯(最近的调用最后): 文件 "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/commands/core.py", 第124行, 在 wrapped中 ret = await coro(arg) 文件 "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/commands/core.py", 第980行, 在 _invoke中 await self.callback(ctx, **kwargs) 文件 "/home/timoha/discord_bot/main.py", 第166行, 在 weather中 async with discord.channel.ChannelType(value=str): 文件 "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/enums.py", 第170行, 在 __call__中 > raise ValueError(f"{value!r} is not a valid {cls.__name__}") > ValueError: <class 'str'> is not a valid ChannelType > > 上述异常是以下异常的直接原因: 回溯(最近的调用最后): 文件 "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/bot.py", 第1114行, 在 invoke_application_command中 await ctx.command.invoke(ctx) 文件 "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/commands/core.py", 第375行, 在 invoke中 await injected(ctx) 文件 "/home/timoha/discord_bot/venv/lib/python3.10/site-packages/discord/commands/core.py", 第132行, 在 wrapped中 > raise ApplicationCommandInvokeError(exc) from exc > discord.errors.ApplicationCommandInvokeError: 应用命令引发异常: ValueError: <class 'str'> is not a valid ChannelType
代码片段
@bot.slash_command(name="weather", description="Погода") async def weather(ctx, *, city: str): city_name = city complete_url = base_url + "appid=" + api_key + "&q=" + city_name response = requests.get(complete_url) x = response.json() channel = ctx.message if x["cod"] != "404": async with discord.channel.ChannelType(value=str): value=str y = x["главный"] current_temperature = y["температура"] current_temperature_celsiuis =str(round(current_temperature - 273.15)) current_pressure = y["давление"] current_humidity = y["влажность"] z = x["погода"] weather_description = z[0]["описание"] weather_description = z[0]["описание"] embed = discord.Embed(title=f"Погода в {city_name}", color=ctx.guild.me.top_role.color, timestamp=ctx.message.created_at,) embed.add_field(name="Описание", value=f"**{weather_description}**", inline=False) embed.add_field(name="Температура(C)", value=f"**{current_temperature_celsiuis}°C**", inline=False) embed.add_field(name="Влажность(%)", value=f"**{current_humidity}%**", inline=False) embed.add_field(name="Atmospheric Pressure(hPa)", value=f"**{current_pressure}hPa**", inline=False) embed.set_thumbnail(url="https://i.ibb.co/CMrsxdX/weather.png") embed.set_footer(text=f"Запрошенный {ctx.author.name}") await channel.send(embed=embed) else: await channel.send("Город не найден.")
问题排查与解决
1. 核心错误根源
代码中async with discord.channel.ChannelType(value=str):这一行完全是错误用法:
ChannelType是Discord.py中的枚举类,用于标识频道类型(如文本频道、语音频道),根本不能用async with上下文管理器包裹- 传入
str类型作为参数也是完全错误的,枚举类需要传入合法的频道类型值(如discord.ChannelType.text) - 这行代码没有任何实际作用,直接删除即可解决当前ValueError。
2. 其他潜在问题修复
除了上述核心错误,代码还有几处需要修正:
- 斜杠命令上下文错误:斜杠命令的
ctx没有message属性,获取当前频道应该用ctx.channel,而不是ctx.message - 天气API键名错误:OpenWeatherMap API返回的是英文键名,你用了俄文键名(如
"главный"、"температура"),会触发KeyError,需要替换为对应的英文键 - 同步请求阻塞事件循环:
requests.get是同步请求,会阻塞Discord.py的事件循环,建议改用异步请求库aiohttp
修改后的完整代码
import aiohttp import discord @bot.slash_command(name="weather", description="Погода") async def weather(ctx, *, city: str): city_name = city complete_url = f"{base_url}appid={api_key}&q={city_name}" # 使用aiohttp异步请求API async with aiohttp.ClientSession() as session: async with session.get(complete_url) as response: x = await response.json() # 斜杠命令中获取当前频道 channel = ctx.channel if x.get("cod") != "404": # 使用API返回的英文键名 y = x["main"] current_temperature = y["temp"] current_temperature_celsius = str(round(current_temperature - 273.15)) current_pressure = y["pressure"] current_humidity = y["humidity"] z = x["weather"] weather_description = z[0]["description"] embed = discord.Embed(title=f"Погода в {city_name}", color=ctx.guild.me.top_role.color, timestamp=ctx.created_at,) # 斜杠命令用ctx.created_at获取时间 embed.add_field(name="Описание", value=f"**{weather_description}**", inline=False) embed.add_field(name="Температура(C)", value=f"**{current_temperature_celsius}°C**", inline=False) embed.add_field(name="Влажность(%)", value=f"**{current_humidity}%**", inline=False) embed.add_field(name="Атмосферное давление(hPa)", value=f"**{current_pressure}hPa**", inline=False) embed.set_thumbnail(url="https://i.ibb.co/CMrsxdX/weather.png") embed.set_footer(text=f"Запрошенный {ctx.author.name}") await channel.send(embed=embed) else: await channel.send("Город не найден.")
内容的提问来源于stack exchange,提问作者Timoha
相关产品推荐
相关产品推荐

