Go에서 표준 접근 방식은 반환 값 error를 통한 오류 처리입니다. 이는 각 지점에서 오류가 발생했을 때 무엇을 할지 명시적으로 제어할 수 있게 해줍니다. Panic은 예기치 않은 재난 상황을 처리하기 위한 메커니즘으로, 가장 가까운 defer까지 실행을 중단하고 recover를 사용하여 "구출"할 수 있습니다. 하지만 recover는 defer 내부에서만 작동합니다.
모범 사례:
func safeDivide(a, b int) (int, error) { if b == 0 { return 0, errors.New("0으로 나누기") } return a/b, nil } func mustDivide(a, b int) int { if b == 0 { panic("0으로 나누기!") } return a/b }
어디에서든 recover를 사용하여 모든 패닉 오류를 "잡을" 수 있나요?
답변: 아니요, recover는 defer 내부에서만 작동하며 패닉이 호출된 동일한 고루틴에서만 작동합니다. 다른 경우에는 패닉이 이(또는 모든) 고루틴의 실행을 중단합니다 — 이는 종종 예상치 못한 결과가 됩니다.
이야기
REST API는 비즈니스 로직의 일반적인 오류 처리를 위해 panic을 사용했습니다. 이로 인해 애플리케이션의 명백하지 않은 충돌과 부정확한 로그가 발생했습니다. recover가 항상 올바르게 작동하지 않았기 때문입니다.
이야기
결제 처리 서비스에서 모든 패닉을 "잡기" 위해 주요 기능에 defer + recover를 구현했지만 고루틴에 대한 것을 잊어버렸습니다 — 자식 고루틴에서는 defer/recover가 없을 경우 애플리케이션이 "무서운" 오류로 충돌하며 일부 거래가 일관되지 않은 상태로 남게 되었습니다.
이야기
복잡한 구조체를 파싱하는 과정에서 오류 반환을 잊고 panic으로 대체했습니다 — 이로 인해 유지 관리와 테스트가 복잡해졌고, 세부 로깅 및 올바른 UX를 확보하기 위해 오류 처리 방식을 완전히 재작성해야 했습니다.