Golang Convention에서 Error Wrapping과 Opaque Error처리가 서로 충돌이 있는것 같아
어떻게 정리를 해야할지를 추가로 정리해봅니다.
1. Opaque Error (불투명한 오류)
"Opaque Error"는 오류 발생 지점에 대한 구체적인 정보가 부족하고, 오직 메시지 문자열만으로 전달되는 형태의 오류를 의미합니다. 이는 오류의 원인을 파악하기 어렵게 하며, 코드 디버깅을 어렵게 만드는 주요 원인입니다. 이 관점에서 살펴보면, 원래 예시 코드에서 문제가 되는 부분은 오류의 맥락이 포함되지 않아서, 오류가 어디에서 발생했는지를 쉽게 알 수 없다는 것입니다.
func AuthenticateRequest(r *Request) error {
err := authenticate(r.User)
if err != nil {
return err // 단순히 원래 오류를 반환함 (Opaque Error)
}
return nil
}
2. Error Wrapping (오류 감싸기)
"Error Wrapping"은 오류 발생 시점에 구체적인 문맥을 추가하여 오류의 원인과 발생 지점을 더 명확히 알 수 있도록 하는 방식입니다. Go 언어에서는 이를 위해 fmt.Errorf 함수와 %w 플래그를 사용하는 방법을 권장합니다.
아래는 개선된 오류 감싸기(Error Wrapping)의 예시입니다.
func AuthenticateRequest(r *Request) error {
err := authenticate(r.User)
if err != nil {
return fmt.Errorf("authenticate failed: %w", err) // 오류에 대한 맥락을 추가하여 wrapping
}
return nil
}
위 코드에서 fmt.Errorf와 %w를 사용하여 authenticate 함수에서 발생한 오류에 "authenticate failed"라는 추가적인 문맥을 더했습니다. 이렇게 하면 오류가 발생했을 때 authenticate에서 오류가 발생했다는 맥락이 유지되므로, 호출 스택을 쉽게 추적할 수 있습니다.
Error Wrapping의 장점:
- 맥락 추가: fmt.Errorf를 통해 추가적인 문맥을 제공함으로써, 오류의 발생 위치와 이유를 명확히 알 수 있습니다.
- 오류 추적: %w 플래그를 사용해 오류를 감싸면, errors.Is와 errors.As 같은 함수로 감싼 오류의 원인을 추적할 수 있어 더 유연하게 오류를 다룰 수 있습니다.
- 유지보수성 증가: 오류의 맥락이 명확하기 때문에, 코드의 유지보수가 쉬워지고 문제 발생 시 빠르게 원인을 파악할 수 있습니다.
3. Opaque Error vs Error Wrapping의 비교
구분 | Opaque Error | Error Wrapping |
오류 정보 | 오류의 원인 파악이 어려움 | 오류에 대한 문맥 추가 |
디버깅 용이성 | 오류의 원인 파악이 어려움 | 오류 발생 지점을 포함해 디버깅 유리 |
유연성 | 오류 전파시 단순 전달 | %w를 사용해 오류를 감싸고 errors.Is, errors.As로 원인 파악 가능 |
사용 예 | return err | return fmt.Errorf("context: %w",err) |
4. Error Wrapping 사례
package main
import (
"errors"
"fmt"
"os"
)
func authenticate(user string) error {
return os.ErrNotExist // 가정: 사용자 인증 시 파일을 찾을 수 없는 오류 발생
}
func AuthenticateRequest(r *Request) error {
err := authenticate(r.User)
if err != nil {
return fmt.Errorf("authenticate failed: %w", err)
}
return nil
}
func main() {
r := &Request{User: "testuser"}
err := AuthenticateRequest(r)
if err != nil {
// errors.Is로 특정 오류 검사
if errors.Is(err, os.ErrNotExist) {
fmt.Println("File does not exist:", err)
} else {
fmt.Println("An error occurred:", err)
}
}
}
type Request struct {
User string
}
위 코드에서 errors.Is(err, os.ErrNotExist)를 사용하여 authenticate에서 발생한 특정 오류(os.ErrNotExist)를 감지할 수 있습니다. fmt.Errorf에서 %w를 사용해 오류를 감쌌기 때문에 이처럼 원래 오류를 추적하는 것이 가능합니다.
결론
- Opaque Error는 오류에 대한 정보가 부족하여 디버깅이 어려운 반면, Error Wrapping은 오류 발생 시점의 문맥을 추가해 디버깅을 쉽게 만들어줍니다.
- 오류를 감싸는 방식으로 처리하면 오류를 추적하기 쉽고, 코드의 유지보수성이 높아집니다.
- Go에서는 fmt.Errorf와 %w를 사용한 오류 감싸기를 권장하며, 이를 통해 더 나은 오류 관리가 가능합니다.
'백엔드 > Golang' 카테고리의 다른 글
Golang Convention 중 논의를 해야 할 사항 정리 (0) | 2024.11.10 |
---|---|
Golang 에러 처리 - (1) Google Guide/Best Practice 찾아보기 (2) | 2024.09.07 |
Golang zero-value 알아보기 (0) | 2024.07.09 |
[번역] Golang vs Spring boot native 성능 비교해보기 - Hello world 케이스 (0) | 2024.07.08 |
Golang init() 사용법 및 주의 사항 (0) | 2024.05.16 |
개발 및 IT 관련 포스팅을 작성 하는 블로그입니다.
IT 기술 및 개인 개발에 대한 내용을 작성하는 블로그입니다. 많은 분들과 소통하며 의견을 나누고 싶습니다.