
2가지 방법으로 Error를 선언할 수 있다.
따라서 두 가지 방법을 나누는 기준에는 sentinel error 에러 인지에 따라 나눈다.
sentinel error는 더 이상 처리할 수 없는 에러를 말한다.
주의 사항
Err~ 형태의 cammel case로 변수명을 선언한다. 또는
~Error 형태의 cammel case로 변수명을 선언한다.
에러 내용에는 대문자를 사용하지 않는다.
에러 내용에는 마침표를 사용하지 않는다.
에러 내용에는 failed 와 같은 단어를 사용하지 않는다.
call stack이 깊어 질수록 err를 반환하는 함수가 늘어가기 마련이다.
불리는 함수 마다 에러를 로깅 한다면 성능상 문제와
정확한 에러 문구를 찾기에도 힘들 것이다.
가장 상위 함수에서 한번만 로깅하자.
callee 함수의 경우에는 cool 하게 caller 에게 아무것도 하지 않고 넘겨 주자.
u, err := getUser(id)
if err != nil {
return fmt.Errorf("get user %q: %w", id, err)
}
// Good:
err1 := fmt.Errorf("err1")
err2 := fmt.Errorf("err2: %w", err1)
err3 := fmt.Errorf("err3: %w", err2)
fmt.Println(err3) // err3: err2: err1
// err3 is a newest-to-oldest error chain, that prints newest-to-oldest.
// Bad:
err1 := fmt.Errorf("err1")
err2 := fmt.Errorf("%w: err2", err1)
err3 := fmt.Errorf("%w: err3", err2)
fmt.Println(err3) // err1: err2: err3
// err3 is a newest-to-oldest error chain, that prints oldest-to-newest.
u, err := getUser(id)
if err != nil {
return fmt.Errorf("get user %q: %w", id, ErrNotFound)
}
이미 선언된 에러코드(ErrNotFound)에 함수의 context를 담고 싶을 때에는
위의 코드 처럼 사용하면 된다.
example)
var (
ErrConnectionFailed = errors.New("connection error")
ErrConnectionTimedOut = errors.New("connection timed out")
)
func DoStuff() error {
return fmt.Errorf("%v : %w", "do stuff", ErrConnectionFailed)
}
func main() {
err := DoStuff()
fmt.Printf("v",err)
log.Errorf("%v",err)
}
결과:
do stuff : connection error
2023/09/25 09:16:51 do stuff : connection error
추후 업데이트
출처: