Golang 학습 노트--error 처리
5273 단어 golang
Golang error 처리
1.1 Golang 공식 라이브러리에 대한 error 지원
(1) Golang의 오류는 비교적 가볍다. Error의 오류는 buildin 패키지에 있는 error의 인터페이스만 실현하면 된다
type error interface {
Error() string
}
(2) Goland의 기본 지원은 errors 패키지의 구현입니다.
// errors.go
package errors
// New returns an error that formats as the given text.
// Each call to New returns a distinct error value even if the text is identical.
func New(text string) error {
return &errorString{text}
}
// errorString is a trivial implementation of error.
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}
(3) 1.3 이후 wrap 지원, 주로 지원하는 Unwrap, Is, As 방법.랩 기능은%w를 사용하지만 스택 정보는 포함되지 않습니다
// wrap.go
func Unwrap(err error) error {
u, ok := err.(interface {
Unwrap() error
})
if !ok {
return nil
}
return u.Unwrap()
}
func Is(err, target error) bool {
if target == nil {
return err == target
}
isComparable := reflectlite.TypeOf(target).Comparable()
for {
if isComparable && err == target {
return true
}
if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
return true
}
// TODO: consider supporting target.Is(err). This would allow
// user-definable predicates, but also may allow for coping with sloppy
// APIs, thereby making it easier to get away with them.
if err = Unwrap(err); err == nil {
return false
}
}
}
func As(err error, target interface{}) bool {
if target == nil {
panic("errors: target cannot be nil")
}
val := reflectlite.ValueOf(target)
typ := val.Type()
if typ.Kind() != reflectlite.Ptr || val.IsNil() {
panic("errors: target must be a non-nil pointer")
}
if e := typ.Elem(); e.Kind() != reflectlite.Interface && !e.Implements(errorType) {
panic("errors: *target must be interface or implement error")
}
targetType := typ.Elem()
for err != nil {
if reflectlite.TypeOf(err).AssignableTo(targetType) {
val.Elem().Set(reflectlite.ValueOf(err))
return true
}
if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) {
return true
}
err = Unwrap(err)
}
return false
}
var errorType = reflectlite.TypeOf((*error)(nil)).Elem()
1.2 golang 공식 라이브러리에 대한 확장 pkg/errors
확장 errors 지원:https://github.com/pkg/errors
pkg/errors는 공식 라이브러리 error에 대한 포장을 제공합니다. 오류 정보를 제공할 뿐만 아니라 오류를 보고하는 창고 정보도 추적할 수 있습니다.
1.3 golang의 오류 유형 처리 자세
(1).Sentinel Error, 미리 정의된 특정 오류는 자신이 errors를 통과하는 것을 가리킨다.New() 메서드는 var Canceled = errors와 같은 정의된 오류를 생성합니다.New("context canceled")
(2).Error type, 사용자 정의 오류 형식은 오류 형식을 정의하여 error를 실현하는 인터페이스를 가리킨다
type MyError struct {
Msg string
File string;
Line int
}
func (e *MyError) Error() string {
return fmt.Sprintf("%s:%d:%s",e.File,e.Line,e.Msg)
}
func test() error {
return &MyError{"Something happened","server.go",42}
}
(3).Opaque errors, 투명화된 errors는 대외적으로 오류가 발생했는지 여부만 제공하고 구체적인 오류 내용 정보는 제공하지 않는 것을 말한다. 다음과 같다.
type temporary interface {
Tempporary() bool
}
func IsTemporary(err error) bool {
te,ok := err.(temporary)
return ok && te.Temporary()
}
대외적으로 IsTemporary() 방법을 제공하여 특정 정보를 대외적으로 제공하지 않고 오류 여부를 검사합니다.
1.4 golang 오류 처리 실천
1. 업무 시스템 응용 프로그램에서 자신이 쓴 함수가 오류로 되돌아오면 errors를 사용합니다.New 또는 errors.Errorf 반환 오류 (스택 정보 저장) (이곳에서 사용하는 pkg/errors 패키지)
2. 업무 시스템 응용 프로그램에서 이 업무 시스템의 다른 패키지나 프로젝트가 되돌아오는 오류가 발생하면 오류가 바로 되돌아옵니다. 예를 들어 서비스층에서dao를 호출하지 않아도 됩니다.
3. 업무 시스템 응용 프로그램에서 호출된 제3자 라이브러리, 표준 라이브러리 또는 자신의 회사 기초 라이브러리를 호출하려면 랩이나 랩프를 사용하여 루트를 포장해야 한다(맨 밑에 있는 오류 정보)
4. 프로그램의 맨 위에 있거나 작업하는goroutine 맨 위에 로그를 출력하고%+v를 사용하여 창고 정보를 기록합니다.만약 이미 일지를 기록했다면, 오류를 위로 던질 필요가 없다.
5. 최상위 재사용 오류.Cause에서 루트 error(근인)를 가져와서 sentinel error와 판단하기
6. 업무 시스템 응용 프로그램에서 대외적으로 error 코드(통일 오류 코드)를 사용하여 외부로 되돌아오기
1.5 간단한 위조 코드 구현
var (
ErrDataNotFound = errors.New("record not found")
)
type User struct {
Id uint64 `json:"Id"`
Name string `json:"name"`
Age int32 `json:"age"`
}
type Dao interface {
Get(id uint64) interface{}
List() interface{}
Create()
Update()
Delete(id uint64)
}
type UserDao struct {}
// Dao , errors Wrap
fuc(user *UserDao) Get(id uint64) (*User, error) {
user := User{}
err := db.Where("id = ?",id).Find(user).Error
if errors.Is(err,sql.ErrNoRows){
retrun errors.Wrap(err,fmt.Sprintf("find user null,user id: %v",id))
}
return &user,nil
}
//
type UserService struct {}
func (s *Service) FindUserByID(userID int) (*model.User, error) {
return dao.FindUserByID(userID)
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
set containerThere is no built-in set container in Go How to implement Set struct{} => type struct{}{} => 0bytes How to create set :=...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.