주제
Go 에서 errors.Is() 함수의 필요성을 정리하고자 함.
그런 함수가 왜 필요함?
Go 에서 error 객체를 다룰 때 현재 실행 흐름에서 호출한 함수에서 던진 error 를 errors.Wrap() 함수를 통해 래핑하여 자식 error 객체로 만들어 반환할 수 있다. (Wrap() 함수에 대해서 이번 글에서는 다루지 않도록 한다.)
이 때 생성된 자식 error 객체가 부모 객체와 “동일” 한지 또는 “할당 가능” 한지 체크하고자 하는 상황이 있을 수 있다.
예를 들자면, 다음 코드이다.
defer func() {
if err := tx.Rollback(); err != nil {
logrus.Error("failed to rollback", err)
}
}()
defer 키워드 다음에 위치한 익명함수는 피호출된 함수 종료시에 호출된다.
이 때 익명함수 내부에 tx.Rollback() 함수는 트랜잭션이 성공하여 커밋된 이후에 호출되면 sql.ErrTxDone 에러를 리턴하는데
정상적으로 트랜잭션이 성공하였음에도, “failed to rollback” 이라는 에러 메시지를 출력하게 된다.
그럴 때 쓰는것이 errors.Is() 함수이다.. 각각 동일 / 할당가능을 체크하여 bool 타입을 리턴한다.
이 중 errors.Is() 함수를 활용해 코드를 다음과 같이 고칠 수 있다.
defer func() {
if err := tx.Rollback(); err != nil && !errors.Is(err, sql.ErrTxDone) {
logrus.Error("failed to rollback", err)
}
}()
err 객체가 sql.ErrTxDone 과 동일한 경우에는 에러 로그를 출력하지 않도록 하여
이제는, 작성자의 의도에 맞도록 트랜잭션의 롤백이 진짜 실패한 경우에만 에러 로그를 출력하도록 구현되었다.
errors.Is(), errors.As() 차이
errors.Is() 함수는 error 타입의 인자인 err, target 두개를 받아 “동일”한지 비교한다.
errors.As() 함수는 error 타입 인자 err, *error 타입 인자 target 두개를 받아 target 에 err 가 “할당 가능” 한지 비교한다.
간단하다. 동일한지 체크하고자 하면 Is(), 할당 가능한지 체크하고자 하면 As() 호출하면 된다.
자세한 로직은 아래 첨부한 GPT 번역 참조.
docs: https://pkg.go.dev/errors#Is
소스코드: https://cs.opensource.google/go/go/+/go1.23.3:src/errors/wrap.go;l=97
docs: https://pkg.go.dev/errors#As
소스코드: https://cs.opensource.google/go/go/+/go1.23.3:src/errors/wrap.go;l=44
'Go' 카테고리의 다른 글
Go 언어 입문 자료 모음 (1) | 2022.06.02 |
---|---|
Go 1.18 (Generic, Fuzzing, go work) (0) | 2022.05.27 |