[Golang] 오류 처리, 깔끔한 방법!
이러한 것 중 하나는 오류 처리입니다. 대부분의 언어 현재 개발자는 OOP 배경에서 왔으며 예외를 처리하는 데 사용되거나 응용 프로그램의 현재 흐름을 중지하기 위해 예외를 "던지는"개념을 가정하고 대부분 이것이 방법이라고 생각합니다. golang에 들어가려면 문제가 발생할 경우를 대비하여 애플리케이션의 흐름을 중지해야 합니다.
글쎄요!
도구를 남용하지 마세요.
저도 많이 봤고 저도 그랬거든요. 그냥
os.exit(1)
예기치 않은 일이 발생할 때마다 계속 진행하십시오. 글쎄, 그것은 go와 함께가는 올바른 방법이 아닙니다!이것이 널리 사용되는 이유를 알 수 있습니다. 대부분의 초기 golang 애플리케이션은 단지 터미널 도구일 뿐이었고 이러한 도구 중 상당수는 .sh 실행 파일을 사용하여 빌드되어 1을 종료하는 데 사용되었습니다. 예상치 못한 일이 발생하여 종료하고 싶다는 것을 나타냅니다.
우리는 이 습관을 우리의 golang 간단한 터미널 응용 프로그램에 적용한 다음 복잡한 응용 프로그램에 적용했습니다. 이는 또 다른 카고 컬트 프로그래밍입니다.
다음과 같이 해야 할 경우를 대비하여 매우 신중하게 수행할 것을 적극 권장합니다.
func main() {
dbConnection := db.connect("...")
defer dbConnection.Close() // this operation won't be executed!
entity := Entity{}
err := dbConnection.Save(entity)
if err != nil {
os.Exist(1)
}
}
오류 전파 고려
오류는 golang의 또 다른 유형일 뿐이며 프로그램 실행 흐름을 제어하려면 오류를 사용해야 합니다.
그렇게 하기 위해서는 적절한 처리 지점까지 프로그램 전체에 이러한 오류를 전파해야 합니다.
클라이언트가 특정 조건으로 주문하는 것을 금지하려는 주문을 관리하기 위한 HTTP API를 고려하십시오. 예를 들면 다음과 같습니다.
package order
// package errors
var (
UnableToShipToCountry = errors.New("unable to ship order to the requested country")
)
type Order struct {
// ... order fields
}
type OrderRepo struct {
DB db
// ...
}
func newOrderFromRequest(o OrderRequest) (Order, error) {
if o.ShippingAddress.Country != "DE" {
return UnableToShipToCountry
}
// ... the creation logic
return Order{...}, nil
}
func (r *OrderRepo)PlaceOrder(o OrderRequest) error {
order, err := newOrderFromRequest(o)
if err != nil {
// don't handle the error here, its handling may differ
return err
}
// ... db transaction may also return an error
return r.db.Save(order)
}
http 핸들러 패키지에서:
package http
http.HandleFunc("/order", func (w http.ResponseWriter, r *http.Request) {
orderRequest := createOrderRequest(r)
err := orderRepo.PlaceOrder(orderRequest)
if errors.Is(err, order.UnableToShipToCountry) {
w.WriteHeader(http.StatusBadRequest)
return
}
if err != nil {
// this error in case of DB transaction failure
w.WriteHeader(http.StatusInternalServerError)
return
}
// ...
w.WriteHeader(http.StatusOK)
})
오류 맞춤설정
오류 추적과 같은 몇 가지 유용한 정보를 여기에 추가하는 것을 고려하면서 사용자 지정 오류 값을 만들고 프로그램 전체에서 사용할 수 있습니다! 특히 디버깅 중에 로그에 유익한 값을 추가할 수 있습니다.
예를 들어:
type AppErr struct {
msg string
code int
trace string
}
func (e AppErr) Error() string {
return fmt.Sprintf("Msg: %s, code: %d, trace:\n %s", e.msg, e.code, e.trace)
}
func NewAppErr(msg string, code int) AppErr {
stackSlice := make([]byte, 512)
s := runtime.Stack(stackSlice, false)
return AppErr{msg, code, fmt.Sprintf("\n%s", stackSlice[0:s])}
}
그리고 우리는 관리자 패키지 내부에 다음과 같은 사용 사례가 있습니다.
패키지 관리자
func A() error {
return b()
}
func b() error {
return NewAppErr("error from b function!", 3)
}
And our main.go is:
func main() {
err := admin.A()
fmt.Println(err)
}
기록된 오류 메시지는 다음과 같습니다.
Msg: error from b function!, code: 3, trace:
goroutine 1 [running]:
./cmd/app/error.NewAppErr({0x1f42b0, 0x17}, 0x7)
./cmd/app/error/error.go:16 +0x35
./cmd/app/admin.b(...)
./cmd/app/admin/admin.go:12
./cmd/app/admin.A(...)
./cmd/app/admin/admin.go:8
main.main()
./cmd/app/main.go:10 +0x8d
prod에서 추적 인쇄를 종료하거나 다른 구성 값을 확인하여 종료하는 것도 고려할 수 있습니다.
도움이 되었기를 바랍니다.
Reference
이 문제에 관하여([Golang] 오류 처리, 깔끔한 방법!), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/mazux/golang-error-handling-the-neat-way-oa2텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)