31차시. 예외 처리 설계
퀴즈 1 — 예외를 State로 바꾸는 안전 실행
노드가 예외를 내도 그래프가 죽지 않게 감싸세요. 오류 이름을 node_error에 남깁니다.
빈칸 코드에서 시작합니다.
def safe(node, state):
pass결과 보기 (예시 풀이)
# 노드를 안전하게 실행하는 함수입니다.
def safe(node, state):
try:
# 정상이면 노드가 돌려준 딕셔너리를 그대로 넘깁니다.
return node(state)
except Exception as error:
# 예외를 다시 던지지 않고, 오류 이름과 안내 문장을 State 조각으로 바꿉니다.
return {"node_error": type(error).__name__, "answer": "잠시 후 다시 시도하세요"}
# 연습용 노드 세 개를 만듭니다.
def ok_node(state):
return {"answer": "환불은 7일 이내에 신청합니다.", "grade": "pass"}
def broken_index_node(state):
# 인덱스가 망가진 상황을 흉내 냅니다.
raise RuntimeError("index corrupted")
def broken_parse_node(state):
# 검증 JSON 파싱이 실패한 상황을 흉내 냅니다.
return int(state["question"])
state = {"question": "환불은 며칠 이내인가요?"}
# 1) 정상 노드: 노드의 반환값이 그대로 나와야 합니다.
print("정상 :", safe(ok_node, state))
# 2) RuntimeError: 그래프가 멈추지 않고 node_error에 이름이 남아야 합니다.
print("인덱스:", safe(broken_index_node, state))
# 3) ValueError: 종류가 다른 예외도 같은 방식으로 잡혀야 합니다.
print("파싱 :", safe(broken_parse_node, state))
# 4) 여러 노드를 이어서 돌려도 중간 오류 때문에 끝까지 가는지 봅니다.
for node in [ok_node, broken_index_node, ok_node]:
result = safe(node, state)
state.update(result)
# 뒤의 정상 노드는 node_error를 return하지 않으므로, 앞에서 적힌 값이 그대로 남습니다.
print("끝까지 실행됨, 남아 있는 node_error:", state.get("node_error"))
실행 결과
정상 : {'answer': '환불은 7일 이내에 신청합니다.', 'grade': 'pass'}
인덱스: {'node_error': 'RuntimeError', 'answer': '잠시 후 다시 시도하세요'}
파싱 : {'node_error': 'ValueError', 'answer': '잠시 후 다시 시도하세요'}
끝까지 실행됨, 남아 있는 node_error: RuntimeError채점 기준: 예외를 다시 raise하면 오답이다.