본문으로 바로가기

Error

category software engineering/backend 2022. 8. 25. 12:28
728x90

https://middlemost.com/failure-is-your-domain/

 

Failure is your Domain

Go's paradox is that error handling is core to the language yet the language doesn't prescribe how to handle errors. We explore how errors are consumed by various roles in your application.

middlemost.com

A blog post: Golang Error Handling — Best Practice in 2020
https://itnext.io/golang-error-handling-best-practice-a36f47b0b94c?gi=4aa392168c6d

 

Golang Error Handling — Best Practice in 2020

analyze different error handling solutions in Golang, and show the best practices by now (go 1.13)

itnext.io

처음 logrus, console에서 나름 정해진 규칙에 맞게 로그를 찍어오다가

# 1
trackingCodeNotFound := strings.Contains(err.Error(), "Cnote No. Not Found.")

// xxx.go
var ErrCnoteNumberNotFound = errors.New("~~ Cnote No. Not Found. ~~")

func getTrackStatus() error {
  return fmt.Errorf("Grab: %w", ErrCnoteNumberNotFound)
}

//
err := getTrackStatus()
trackingCodeNotFound := errors.Is(err, ErrCnoteNumberNotFound)

# 2
return nil, errors.New("not implemented")

Datadog을 도입하면서 Log를 Wrapping 해야지 찾기 쉽다는걸 느꼈다.

GRPC를 사용하면서 https://cloud.google.com/apis/design/errors

 

오류  |  Cloud API  |  Google Cloud

의견 보내기 오류 이 장에서는 Google API 오류 모델의 개요를 제공합니다. 또한 개발자가 오류를 올바르게 생성 및 처리할 수 있는 방법에 대한 일반적인 지침을 설명합니다. Google API는 프로토콜

cloud.google.com

에러 디자인을 참조하고,

# specific service error
enum Error {
	Error_Unused = 0; // The first enum value must be zero in proto3.
	RecordNotFound = 1;
	Forbidden = 2;
	RecordCreate = 3;
	InvalidRequestBody = 4;
	InvalidParam = 5;
	InvalidQuery = 6;
	Internal = 7;
	NoneExistingLineItem = 8;
	ProductNotAvailable = 9;
	ProductIsNotActive = 10;
	ProductIsNotReleasedYet = 11;
	ProductIsNotPublishedYet = 12;
	ProductIsNotPublishedAnymore = 13;
	CartDoesNotHaveItems = 14;
	LessThanMinQuanity = 15;
	ExceedsMaxQuantity = 16;
	CartProductTypeMismatch = 17;
	InvalidCartItemNoteType = 18;
	ItemNoteIsNotInCart = 19;
	NeedToStartTransaction = 20;
	TransactionAlreadyStarted = 21;
	InvalidQuantity = 22;
	InvalidFreeItemSelection = 23;
	ProductNotFound = 24;
	InputNoteRequired = 25;
	InputNoteFieldRequired = 26;
	BundleItemNotFound = 27;
	BundledProductNotFound = 28;
	ProductOutOfStock = 29;
	CartIsEmpty = 30;
	ShippingRateNotFound = 31;
	InvalidVoucherCondition = 32;
	InactiveVoucher = 33;
}

# common error
enum Error {
	Error_Unused = 0; // The first enum value must be zero in proto3.
	RecordNotFound = 1;
	Forbidden = 2;
	RecordCreate = 3;
	InvalidRequestBody = 4;
	InvalidParam = 5;
	InvalidQuery = 6;
	Internal = 7;
}
// NewError - Create an error with code and message
func NewError(code errors.Error, message string) *commonerror.Error {
	return factory.NewError(code, message)
}

// WrapError - Wrap other library error with our error code
func WrapError(code errors.Error, err error) *commonerror.Error {
	return factory.WrapError(code, err)
}

// SimpleError - Create an error with just code. Message came from predefined string or enum name
func SimpleError(code errors.Error) *commonerror.Error {
	return factory.SimpleError(code)
}

// GetErrorCode - Return idl defined error code if passed error is commonerrors.Error type
func GetErrorCode(e error) errors.Error {
	err, ok := e.(*commonerror.Error)
	if !ok {
		return -1
	}
	return errors.Error(err.Code)
}

// Is - Return true if passed error is commonerrors.Error type and error code is same as passed code
func Is(e error, expected errors.Error) bool {
	code := GetErrorCode(e)
	return code == expected
}

// GetDetail - Return detail if passed error is commonerrors.Error type
func GetDetail(e error) interface{} {
	err, ok := e.(*commonerror.Error)
	if !ok {
		return nil
	}
	return err.Detail
}

로 Wrap해서 같은 방식으로 추적하기 편하게 변경하

'software engineering > backend' 카테고리의 다른 글

gRPC Error  (0) 2022.08.26
go-pprof  (0) 2022.08.25
Topicctl (Kafka management)  (0) 2022.08.25
gRPC  (0) 2022.08.25
Slow Query (feat. index)  (0) 2022.08.25