C.W.K.
Stream
Lesson 06 of 06 · published

ExceptionGroup 와 except* — 동시 여러 예외

~18 min · exceptiongroup, except-star, 3.11, asyncio

Level 0호기심
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete

새 모양 (3.11+) — 비행 중 여러 예외

Python 3.11 까진 예외 raise + 잡기가 엄격히 직렬 — 한 번에 하나. 근데 동시성 코드 — asyncio 의 TaskGroup, 병렬 I/O, 배치 연산 — 가끔 동시에 여러 개 실패. ExceptionGroup 이 언어의 답 — 다른 거들의 list 감싸는 단일 예외, except* 가 그룹 안 특정 타입 처리 새 문법.

ExceptionGroup — 예외 list 감쌈

ExceptionGroup(message, list_of_excs) raise. 그룹 자체가 예외, 구성 예외들이 .exceptions 로 접근 가능. traceback 이 전체 트리 보여.

except* — 타입 잡고 나머지 두기

except* SomeError as eg: 가 그룹 안의 모든 SomeError 잡음, 중첩 깊이 무관. 바인딩된 eg 가 매치된 거만 담은 *새* ExceptionGroup. 원래 그룹의 다른 예외는 계속 전파, 여러 except* 블록이 각자 자기 타입 잡음.

asyncio.TaskGroup — 처음 만나는 곳

실제 코드에서 ExceptionGroup 의 가장 흔한 생산자는 asyncio.TaskGroup (3.11+). 여러 task 가 동시 실패하면 그룹이 모든 예외 한 ExceptionGroup 으로 묶음. 처리 — try: async with TaskGroup() as tg: ...; except* OneType as eg: ...; except* OtherType as eg: ....

원칙: 대부분 애플리케이션 코드는 ExceptionGroup 직접 구축 안 필요. 주로 TaskGroup 또는 다른 동시성 primitive 쓸 때 만나. except* 문법 알면 다중 실패 케이스 깔끔히 처리.

Code

ExceptionGroup raise + 잡기·python
# Python 3.11+
try:
    raise ExceptionGroup(
        "여러 문제",
        [
            ValueError("잘못된 값"),
            KeyError("없음"),
            TypeError("잘못된 모양"),
        ],
    )
except* ValueError as eg:
    print("value 에러 잡음:", [str(e) for e in eg.exceptions])
except* KeyError as eg:
    print("key 에러 잡음:", [str(e) for e in eg.exceptions])
# 원래 그룹의 TypeError 는 위로 전파 — 둘 다 except* 에 안 매치
asyncio.TaskGroup 의 ExceptionGroup (3.11+)·python
# import asyncio
#
# async def fail_a():
#     raise ValueError("a 실패")
#
# async def fail_b():
#     raise KeyError("b 실패")
#
# async def main():
#     try:
#         async with asyncio.TaskGroup() as tg:
#             tg.create_task(fail_a())
#             tg.create_task(fail_b())
#     except* ValueError as eg:
#         print("value 에러:", [str(e) for e in eg.exceptions])
#     except* KeyError as eg:
#         print("key 에러:", [str(e) for e in eg.exceptions])
#
# asyncio.run(main())
# 두 task 동시 실행, 두 실패 그룹에 수집, 둘 다 처리.
중첩 ExceptionGroup — except* 가 평탄히 봄·python
try:
    raise ExceptionGroup(
        "바깥",
        [
            ValueError("v1"),
            ExceptionGroup("안", [ValueError("v2"), KeyError("k1")]),
        ],
    )
except* ValueError as eg:
    print("모든 ValueError:", [str(e) for e in eg.exceptions])
    # v1 (top level) 와 v2 (중첩) 둘 다 — except* 가 재귀
except* KeyError as eg:
    print("모든 KeyError:", [str(e) for e in eg.exceptions])
except* 없이 — 단일 처리 (legacy 스타일)·python
# 3.11 없거나 옛 스타일 처리 원하면
try:
    raise ExceptionGroup("문제", [ValueError("x"), KeyError("y")])
except ExceptionGroup as eg:
    for e in eg.exceptions:
        print("개별:", type(e).__name__, e)
# 작동하지만 중첩 처리 X — 그건 except* 필요

External links

Exercise

ExceptionGroup 구축 — 세 구성 — ValueError, KeyError, 그리고 TypeError 와 두 번째 ValueError 담은 중첩 ExceptionGroup. try/except* 블록 — 한 분기에 모든 ValueError, 다른 분기에 모든 KeyError. 각 분기에서 예외 메시지 출력. 중첩된 ValueError 가 except* 로 정확히 같이 묶이는지 확인.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.