gin 에서 에러 핸들링을 처리 할 때, 보통 middleware 를 하나 만들어 처리를 한다.
검색을 했을 때, 괜찮은 방법들이 없어서 생각하며 만들었는데
지금 다시 찾아보니까 이 방법 괜찮은것 같다.
(적용을 한번 해보고 더 나은 방식으로 할 필요가 있겠다)
https://www.mo4tech.com/use-middleware-for-global-error-handling-in-gin.html
Use middleware for global error handling in Gin - Moment For Technology
mo4tech.com (Moment For Technology) is a global community with thousands techies from across the global hang out!Passionate technologists, be it gadget freaks, tech enthusiasts, coders, technopreneurs, or CIOs, you would find them all here.
www.mo4tech.com
Posted on Sept. 12, 2022, 8:14 p.m. by Aaryahi Keer
본인이 만든 방식은 middleware 쪽에서 처리한 부분은 아니고
error.go 라는 파일을 하나 만들어 import 하는 방식으로 처리했다.
간단하게 예를 들어보면
먼저 error code 를 상수로 정의했다.
많은 에러들이 있지만, 각각의 database table 에 맞는 에러코드 및
프로젝트에 맞는 에러코드를 추가해주면 된다.
const (
INVALID_PARAMS = 100000
ERROR_SERVER = 100001
AUTHORIZATION_HEADER_NOT_FOUND = 110000
EXPIRED_TOKEN = 110001
INVALID_TOKEN = 110002
NOT_FOUND_PAGE = 120000
)
숫자는 프로젝트를 하는 사람들과의 약속으로 정하면 된다.
그 다음 각 상수의 에러내용을 좀 더 구체적으로 작성했다.
var msg = map[int]map[string]int{
INVALID_PARAMS: {"Invalid params": http.StatusBadRequest},
ERROR_SERVER: {"Server error": http.StatusInternalServerError},
AUTHORIZATION_HEADER_NOT_FOUND: {"Authorization header not found": http.StatusBadRequest},
EXPIRED_TOKEN: {"Expired token": http.StatusUnauthorized},
INVALID_TOKEN: {"Invalid token": http.StatusUnauthorized},
NOT_FOUND_PAGE: {"Page not found": http.StatusNotFound},
}
그 다음 msg 를 가져오는 코드를 작성한다.
func getErrorMsg(code int) (string, int) {
msg, ok := msg[code]
if ok {
for message, httpStatus := range msg {
return message, httpStatus
}
}
return "", 0 // ok 가 false 일 때, 임시적으로 return "", 0 을 해놓았는데 이것도 정하면 된다. 에러코드가 정의 되어있지 않은 경우이다.
}
에러코드를 check 하는 코드를 작성한다.
func CheckErrorCode(c *gin.Context, err error, code int) bool {
if err != nil {
message, httpStatus := getErrorMsg(code) // message 와 http 상태코드 가져온다.
c.JSON(httpStatus, gin.H{
"code": code,
"message": message,
})
c.Abort() // Abort 처리 까지 해준다.
return true
}
return false
}
직접 사용 할때는
예를 들어 Gin 에서 ShouldBindJSON 사용하여 body 값을 받을 때
// func (*gin.Context).ShouldBindJSON(obj any) error
err := c.ShouldBindJSON(&body)
if CheckErrorCode(c, err, 100000) {
return
}
이런식으로 처리 할 수 있다.
에러를 반환하지 않는 예를 들어 string 빈 값을 체크 하거나 할 때는
errors 를 import 하여 강제로 에러 메시지를 넣어주면 된다.
import (
"errors"
)
// func (*gin.Context).Query(key string) (value string)
name := c.Query("name")
if name == "" {
if CheckErrorCode(c, errors.New("err"), 100000) {
return
}
}
방법은 많고 본인이 편한 방법을 사용하면 된다.
위 링크의 방식도 괜찮아서 저 방법으로도 구현을 해봐야겠다.