더북(TheBook)

6.2.3 사용자 정의 에러 타입

에러는 에러가 발생한 상황에 따라 적절한 조치를 취할 수 있게 최대한 구체적으로 만들어야 한다. 에러 메시지와 에러 상황에 대한 추가 정보(예를 들면 매개변수 값, 열려는 파일 경로 등)를 담아 에러 타입을 직접 만들면 활용도가 높다.

Error() string 메서드를 가진 타입은 모두 에러로 사용할 수 있으므로 에러 타입을 구조체로 직접 정의할 수도 있다.

SqrtError를 정의하여 Sqrt() 함수를 다시 작성해 보았다.

import (
    "fmt"
    "math"
    "time"
)
 
type SqrtError struct {
    time    time.Time // 에러가 발생한 시간
    value   float64   // 에러를 발생시킨 값
    message string    // 에러 메시지
}
 
// error 인터페이스에 정의된 Error() 메서드 구현
func (e SqrtError) Error() string {
    return fmt.Sprintf("[%v]ERROR - %s(value: %g)", e.time, e.message, e.value)
}
 
func Sqrt(f float64) (float64, error) {
    // 매개변수로 전달된 값이 유효한 값이 아닐 때 SqrtError를 반환
    if f < 0 {
        return 0, SqrtError{time: time.Now(), value: f, message: "음수는 사용할 수 없습니다"}
    }
    if math.IsInf(f, 1) {
        return 0, SqrtError{time: time.Now(), value: f, message: "무한대 값은 사용할 수 없습니다"}
    }
    if math.IsNaN(f) {
        return 0, SqrtError{time: time.Now(), value: f, message: "잘못된 수입니다"}
    }
     
    // 정상 처리 결과 반환
    return math.Sqrt(f), nil
}

SqrtError 타입은 에러가 발생한 시간과 에러를 발생시킨 값, 에러 메시지를 담고 있다. Error() 메서드는 에러가 발생한 시간과 에러를 발생시킨 값을 담은 에러 메시지를 생성하여 반환한다.


func main() {
    v, err := Sqrt(9) // 9의 제곱근. 정상 동작
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(v)
   
    v, err = Sqrt(-9) // -1의 제곱근. 에러 발생
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(v)
}

실행 결과

3
2015/12/10 22:35:02 [2015-12-10 22:35:02.488188734 +0900 KST]ERROR - 음수는 사용할 수 없습니다(value: -9) exit status 1

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.