본문으로 바로가기
728x90
반응형

이전글보기

[정보/Discord Bot] - [discord.py 2.0] 09. Cogs를 생성하여 소스코드 분할하기

[정보/Discord Bot] - [discord.py 2.0] 10. Bot을 종료하지 않고 Cogs reload 하기

[정보/Discord Bot] - [discord.py 2.0] 11. 메세지에 버튼 추가하기

[정보/Discord Bot] - [discord.py 2.0] 12. Select 기능 추가하기

[정보/Discord Bot] - [discord.py 2.0] 13. Modal 기능으로 사용자입력창 띄우기


그동안은 코드에 무언가 잘못입력해서 명령어가 제대로 출력되지 않을때 아무런 문구가 뜨지 않는 경우가 많아 영문을 모를때가 많았는데요..?

이번 포스팅에선 디스코드 봇이 작동하는 도중 오류가 발생했을 때, 사용자가 알 수 있도록 예외처리를 할겁니다.

사용할 reference 는 다음과 같습니다

명령어 입력을 통해 진행되는 동작 도중 아무 예외처리 없이 exception 이 발생했을때 발생되는 함수입니다.

 

event를 처리하는 bot에다가 추가하는 것이기 때문에 main.py 에서 위 event를 추가해 줍니다.

1
2
3
4
5
6
7
8
9
10
11
@app.event
async def on_command_error(ctx, error):
    if isinstance(error, commands.CommandNotFound):
        embed = discord.Embed(title="몰?루", description="입력하신 명령어는 존재하지 않는 명령어입니다", color=0xFF0000)
        await ctx.reply(embed=embed)
        return
    else:
        embed = discord.Embed(title="오류!!", description="예상치 못한 오류가 발생했습니다.", color=0xFF0000)
        embed.add_field(name="상세", value=f"```{error}```")
        await ctx.reply(embed=embed)
        return
cs

예외처리는 간단하게 존재하지 않는 명령어 입력시 발생되는  "commands.CommandNotFound" exception만 추가하였습니다

 

@app.event

1 : app의 event 를 작성합니다.

 

async def on_command_error(ctx, error):

2 : on_command_error 함수를 오버라이딩 합니다.

 

if isinstance(error, commands.CommandNotFound):

3 : 발생한 에러가 "commands.CommandNotFound" 인 경우의 조건문 입니다.

 

 embed = discord.Embed(title="몰?루", description="입력하신 명령어는 존재하지 않는 명령어입니다", color=0xFF0000)
 await ctx.reply(embed=embed)
 return

4~6 : 등록되지 않은 명령어를 입력하였을때 출력할 embed를 전송하고 함수를 종료합니다.

 

    else:
        embed = discord.Embed(title="오류!!", description="예상치 못한 오류가 발생했습니다.", color=0xFF0000)
        embed.add_field(name="상세", value=f"```{error}```")
        await ctx.reply(embed=embed)
        return

7~11 : 그외 모든 오류가 발생하였을 때, 발생한 오류항목을 embed에 추가해주고 서버에 전송합니다.

 

위와같이 입력했을때, 등록되지 않은 명령어를 입력할 경우 다음과 같이 출력됩니다.

 

완성된 main.py 소스코드입니다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import asyncio
import os
import discord
from discord.ext import commands
 
intents = discord.Intents.all()
app = commands.Bot(command_prefix='!', intents=intents)
 
 
async def load_extensions():
    for filename in os.listdir("Cogs"):
        if filename.endswith(".py"):
            await app.load_extension(f"Cogs.{filename[:-3]}")
    # cog 하나씩 불러오기
    # activate_list = ["ping"]
    # for name in activate_list:
    #     await app.load_extension(f"Cogs.{name}")
 
 
@app.command(name="reload")
async def reload_extension(ctx, extension=None):
    if extension is not None:
        await unload_function(extension)
        try:
            await app.load_extension(f"Cogs.{extension}")
        except commands.ExtensionNotFound:
            await ctx.send(f":x: '{extension}'을(를) 파일을 찾을 수 없습니다!")
        except (commands.NoEntryPointError, commands.ExtensionFailed):
            await ctx.send(f":x: '{extension}'을(를) 불러오는 도중 에러가 발생했습니다!")
        else:
            await ctx.send(f":white_check_mark: '{extension}'을(를) 다시 불러왔습니다!")
    else:
        for filename in os.listdir("Cogs"):
            if filename.endswith(".py"):
                await unload_function(filename[:-3])
                try:
                    await app.load_extension(f"Cogs.{filename[:-3]}")
                except commands.ExtensionNotFound:
                    await ctx.send(f":x: '{filename[:-3]}'을(를) 파일을 찾을 수 없습니다!")
                except (commands.NoEntryPointError, commands.ExtensionFailed):
                    await ctx.send(f":x: '{filename[:-3]}'을(를) 불러오는 도중 에러가 발생했습니다!")
        await ctx.send(":white_check_mark: reload 작업을 완료하였습니다!")
 
 
@app.command(name="unload")
async def unload_extension(ctx, extension=None):
    if extension is not None:
        await unload_function(extension)
        await ctx.send(f":white_check_mark: {extension}기능을 종료했습니다!")
    else:
        await unload_function(None)
        await ctx.send(":white_check_mark: 모든 확장기능을 종료했습니다!")
 
 
async def unload_function(extension=None):
    if extension is not None:
        try:
            await app.unload_extension(f"Cogs.{extension}")
        except (commands.ExtensionNotLoaded, commands.ExtensionNotFound):
            pass
    else:
        for filename in os.listdir("Cogs"):
            if filename.endswith(".py"):
                try:
                    await app.unload_extension(f"Cogs.{filename[:-3]}")
                except (commands.ExtensionNotLoaded, commands.ExtensionNotFound):
                    pass
 
 
@app.event
async def on_command_error(ctx, error):
    if isinstance(error, commands.CommandNotFound):
        embed = discord.Embed(title="몰?루", description="입력하신 명령어는 존재하지 않는 명령어입니다", color=0xFF0000)
        await ctx.reply(embed=embed)
        return
    else:
        embed = discord.Embed(title="오류!!", description="예상치 못한 오류가 발생했습니다.", color=0xFF0000)
        embed.add_field(name="상세", value=f"```{error}```")
        await ctx.reply(embed=embed)
        return
 
 
async def main():
    async with app:
        await load_extensions()
        file = open("discord_token.txt")
        bot_token = file.readline()
        file.close()
        await app.start(bot_token)
 
 
asyncio.run(main())
cs

 


포스팅에 사용된 모든 소스코드는 아래 Github에서 확인하실 수 있습니다.

https://github.com/aochfl/ChoRi_TestBot

 

GitHub - aochfl/ChoRi_TestBot

Contribute to aochfl/ChoRi_TestBot development by creating an account on GitHub.

github.com


참고자료

https://discord.com/developers/docs/reference - ( Discord Developer API )

https://discordpy.readthedocs.io/en/latest/index.html  -  ( discord.py library 문서 )

 

728x90
반응형