5. 명령어 에러처리

chaejm55·2021년 3월 18일
1

디스코드봇

목록 보기
6/18
post-thumbnail

0. 들어가기 전에

디스코드 봇 명령어는 일반적인 에러가 아닌 특수한 에러를 발생시킨다. 따라서 try - except 구문으로 처리가 되지 않는 에러이다. 발생할 법한 오류에서 간단하게 에러를 발생시키지 않는 방법을 소개했다. 이번엔 그 에러를 처리하는 방법을 소개하겠다.

1. 명령어 에러 발생 예시

1.봇과 함께 놀기 포스팅에 이러한 특수 에러가 발생 할 수 있다고 예시를 들었다. !game 뒤에 필요한 파라미터가 입력 되지 않아서 생기는 에러이고, 자세히 살펴보면 discord.ext.commands.errors에 정의된 오류임을 알 수 있다.
더 많은 명령어 특수 에러들의 종류를 살펴보자.

2. 주요 명령어 에러들

  • MissingRequiredArgument: 위에서 말한 것과 같이 필요한 파라미터를 입력하지 않아서 발생하는 에러이다.

  • BadArgument: 명령어로 받은 파라미터가 파싱이나 변환이 실패할 때, 즉 올바르지 않은 타입의 파라미터를 입력하면 발생하는 에러이다.

  • MissingPermission: 아직은 다루지 않았지만 명령어에 권한 제한을 두었을 때, 권한이 없는 사용자가 명령어를 실행시켰을 때 발생하는 에러이다.


디스코드 공식문서 에러 부분 링크

https://discordpy.readthedocs.io/en/latest/ext/commands/api.html?highlight=error#exceptions

3. 코드 예시

명령어를 만들때 처럼 데코레이터를 사용하여 비동기 함수로 작성한다.
파라미터에는 ctx와 error가 함께 들어가야한다.

  1. MissingRequiredArgument
@bot.command()
async def game(ctx, user: str):
    rps_table = ['가위', '바위', '보']
    bot = random.choice(rps_table)
    result = rps_table.index(user) - rps_table.index(bot)
    if result == 0:
        await ctx.send(f'{user} vs {bot}  비겼습니다.')
    elif result == 1 or result == -2:
        await ctx.send(f'{user} vs {bot}  유저가 이겼습니다.')
    else:
        await ctx.send(f'{user} vs {bot}  봇이 이겼습니다.')


@game.error  # @<명령어>.error의 형태로 된 데코레이터를 사용한다.
async def game_error(ctx, error):  # 파라미터에 ctx, error를 필수로 한다.
    if isinstance(error, MissingRequiredArgument):  # isinstance로 에러에 따라 시킬 작업을 결정한다.
        await ctx.send("가위/바위/보 중 낼 것을 입력해주세요.")

실행결과

2. BadArgument

@bot.command(name="숫자")
async def num_echo(ctx, user: int):
    await ctx.send(f"입력한 숫자는 {user}입니다.")


@num_echo.error
async def num_echo_error(ctx, error):
    if isinstance(error, BadArgument):
        await ctx.send("정수를 입력 해주세요")

실행결과

MissingPermissions는 추후 명령어 권한 부여 시 예시를 제시하겠다.

4. 마무리

try - except 구문으로도 잡아지지 않아 골치아팠던 에러들을 잡는 방법을 배워봤다. 에러 처리 부분은 여건이 된다면 매 포스팅마다 발생할 법한 에러 부분에서 다룰 예정이다.

github 전체 코드

time.sleep(259200)
profile
여러가지를 시도하는 학생입니다

0개의 댓글