Search code examples
pythonherokudiscord.py

How to fix RuntimeWarning: Enable tracemalloc to get the object allocation traceback error


So I have a discord bot that has music commands in it. Today I added that if the bot doesn't play anthing in 5 mins, it will leave the voice channel.

def search(arg):
    global last_played
    last_played = arg
    try:
        requests.get("".join(arg))
    except:
        arg = " ".join(arg)
    else:
        arg = "".join(arg)
    with youtube_dl.YoutubeDL(YDL_OPTIONS) as ydl:
        info = ydl.extract_info(f"ytsearch:{arg}", download=False)['entries'][0]

    return {'source': info['formats'][0]['url'], 'title': info['title']}


async def check_timer(ctx):
    global last_played
    guild = ctx.message.guild
    voice_client = guild.voice_client
    voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
    music_check = last_played
    await asyncio.sleep(300)
    if not voice.is_playing() and music_check == last_played:
        await voice_client.disconnect()
        await ctx.send("No song is queued for 5 minutes. Left the voice channel!")


def play_next(ctx):
    voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
    if len(song_queue) > 1:
        del song_queue[0]
        voice.play(discord.FFmpegPCMAudio(song_queue[0]['source'], **FFMPEG_OPTIONS), after=lambda e: play_next(ctx))
        voice.is_playing()
    else:
        asyncio.create_task(check_timer(ctx))


@client.command()
async def play(ctx, *arg):
    channel = ctx.message.author.voice.channel

    if channel:
        voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
        song = search(arg)
        song_queue.append(song)

        if voice and voice.is_connected():
            await voice.move_to(channel)
        else:
            voice = await channel.connect()

        if not voice.is_playing():
            voice.play(discord.FFmpegPCMAudio(song_queue[0]['source'], **FFMPEG_OPTIONS), after=lambda e: play_next(ctx))
            voice.is_playing()
        else:
            await ctx.send("Added to queue")
    else:
        await ctx.send("You're not connected to any channel!")

And the thing is when I run the bot. I get this error

2021-01-02T14:49:20.462802+00:00 app[worker.1]: Traceback (most recent call last):
2021-01-02T14:49:20.462823+00:00 app[worker.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/discord/player.py", line 611, in _call_after
2021-01-02T14:49:20.462824+00:00 app[worker.1]:     self.after(error)
2021-01-02T14:49:20.462825+00:00 app[worker.1]:   File "/app/main.py", line 219, in <lambda>
2021-01-02T14:49:20.462834+00:00 app[worker.1]:     voice.play(discord.FFmpegPCMAudio(song_queue[0]['source'], **FFMPEG_OPTIONS), after=lambda e: play_next(ctx))
2021-01-02T14:49:20.462837+00:00 app[worker.1]:   File "/app/main.py", line 201, in play_next
2021-01-02T14:49:20.462838+00:00 app[worker.1]:     asyncio.create_task(check_timer(ctx))
2021-01-02T14:49:20.462838+00:00 app[worker.1]:   File "/app/.heroku/python/lib/python3.9/asyncio/tasks.py", line 360, in create_task
2021-01-02T14:49:20.462839+00:00 app[worker.1]:     loop = events.get_running_loop()
2021-01-02T14:49:20.462859+00:00 app[worker.1]: RuntimeError: no running event loop
2021-01-02T14:49:20.470913+00:00 app[worker.1]: /app/.heroku/python/lib/python3.9/site-packages/discord/player.py:615: RuntimeWarning: coroutine 'check_timer' was never awaited
2021-01-02T14:49:20.470914+00:00 app[worker.1]:   traceback.print_exception(type(exc), exc, exc.__traceback__)
2021-01-02T14:49:20.470915+00:00 app[worker.1]: RuntimeWarning: Enable tracemalloc to get the object allocation traceback

I searched up in the net and saw some people with the same error but their solution was to put await somewhere, I couldn't see any place that needs an await.

PS I'm using heroku to host the bot.


Solution

  • This is the line that's causing the error

    asyncio.create_task(check_timer(ctx))
    

    Here's explained why.

    To fix it:

    task = client.loop.create_task(check_timer(ctx))
    # or
    loop = asyncio.get_event_loop()
    task = loop.create_task(check_timer(ctx))
    
    await task
    

    Reference: