[go] 에러 처리를 위한 리펙토링 전략

에러 처리는 모든 프로그래밍 언어에서 중요한 주제입니다. 특히 Go 언어에서는 에러 처리가 명시적으로 이루어지며, 이에 따라 코드의 가독성과 유지보수성이 크게 영향을 받습니다. 이번 포스트에서는 Go 언어에서의 에러 처리를 위한 리팩터링 전략을 알아보도록 하겠습니다.

1. 에러 타입 생성

첫 번째 전략은 에러 타입을 생성하는 것입니다. 때로는 특정 에러에 대해 사용자 정의 타입을 만들어 명시적으로 처리하는 것이 도움이 될 수 있습니다. 아래는 간단한 사용자 정의 에러 타입의 예시입니다.

type MyError struct {
    Msg string
    Code int
}

func (e *MyError) Error() string {
    return e.Msg
}

func doSomething() error {
    if err := someFunction(); err != nil {
        return &MyError{Msg: "Something went wrong", Code: 500}
    }
    return nil
}

이렇게 하면 doSomething 함수에서 발생한 에러를 명시적으로 처리할 수 있으며, 에러에 대한 추가 정보를 담을 수 있습니다.

2. 에러 처리 공통 함수 사용

두 번째 전략은 에러 처리를 위한 공통 함수를 사용하는 것입니다. 에러를 처리하는 코드는 종종 반복되는데, 이를 하나의 함수로 추출하여 중복을 줄일 수 있습니다. 아래는 에러를 처리하는 공통 함수의 예시입니다.

func handleError(err error, msg string) {
    if err != nil {
        log.Printf("%s: %v", msg, err)
    }
}

func main() {
    if err := doSomething(); err != nil {
        handleError(err, "Failed to do something")
    }
}

이렇게 함으로써 에러 처리 코드의 반복을 줄일 뿐만 아니라, 에러에 대한 일관된 로깅을 할 수 있습니다.

3. 에러 타입 확인과 형변환

마지막 전략은 에러 타입을 확인하고 형변환하는 것입니다. 때로는 특정 타입의 에러에 대해서만 처리를 수행해야 하는 경우가 있습니다. 이때 type assertion을 사용하여 에러의 타입을 확인하고 해당하는 처리를 수행할 수 있습니다.

func doSomething() error {
    if err := someFunction(); err != nil {
        return fmt.Errorf("something went wrong: %v", err)
    }
    return nil
}

func main() {
    if err := doSomething(); err != nil {
        if e, ok := err.(*MyError); ok {
            // MyError 타입에 대한 처리
            fmt.Println("Custom error:", e.Code, e.Msg)
        } else {
            // 기타 에러에 대한 처리
            fmt.Println("Generic error:", err)
        }
    }
}

이렇게 하면 특정 타입의 에러에 대해서만 추가적인 처리를 할 수 있으며, 코드의 가독성과 유지보수성을 높일 수 있습니다.

에러 처리는 프로그램의 안정성과 신뢰성을 높이는 중요한 요소이므로, 올바른 리팩터링 전략을 통해 코드를 보다 견고하게 만들 수 있습니다.

참고 자료: