개발/Go

[Gin] GORM 디버깅 & 에러 핸들링 완전정복

devhooney 2025. 6. 13. 07:45
728x90

 

에러 무시하다가 큰일난다 - 실전에서 통하는 GORM 디버깅 & 예외 처리 전략

 

 

 

 


 

 

 

✅ 목차


GORM 에러 핸들링의 기본 구조
RowsAffected로 실패 원인 파악하기
특정 에러 구분하기 (errors.Is, errors.As)
로그 레벨 조절로 SQL 추적하기
실전 예제: 유저 존재 확인 후 조건부 저장
디버깅 꿀팁 & 실수 피하기

 

 

 

728x90

 

 

 

 

1. GORM 에러 핸들링 기본 구조

 

GORM의 대부분 메서드는 .Error 필드에 에러를 담는다.

user := User{}
err := db.First(&user, 1).Error
if err != nil {
    // 에러 처리
}

 

하지만 이렇게만 쓰면 에러 원인을 정확히 알기 어렵다.

 

 


 

 

2. RowsAffected로 레코드 유무 판단하기


쿼리는 성공했지만 데이터가 없을 때는 에러가 없고 RowsAffected만 0일 수 있다.

result := db.First(&user, 9999)
if result.Error != nil {
    log.Println("DB error:", result.Error)
} else if result.RowsAffected == 0 {
    log.Println("데이터 없음")
}

 

✔ Find는 에러 없이 RowsAffected만 0으로 반환함

var users []User
db.Where("age > ?", 100).Find(&users)
// 에러 없음 but users는 비어 있을 수 있음!

 

 

 

 


 

 

3. 에러 타입 분기처리 — errors.Is, errors.As


Go 1.13+에서는 에러를 구체적으로 분기할 수 있다.

❗ record not found 처리

if errors.Is(err, gorm.ErrRecordNotFound) {
    log.Println("유저를 찾을 수 없습니다")
}

 

📌 사용자 정의 에러와의 조합도 가능

var myErr *MyCustomError
if errors.As(err, &myErr) {
    log.Println("내가 정의한 에러 발생:", myErr.Code)
}

 

 

 

 

 

 


 

4. GORM 로그 레벨 설정하기 (쿼리 추적)


GORM은 자체 로거를 통해 실행된 SQL, 에러, 슬로우 쿼리 등을 추적할 수 있다.

import (
  "gorm.io/gorm/logger"
  "time"
)

db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{
  Logger: logger.Default.LogMode(logger.Info),
})

 

로그 레벨 종류
- logger.Silent: 출력 안 함
- logger.Error: 에러만 출력
- logger.Warn: 경고 이상 출력
- logger.Info: 쿼리 전부 출력 (개발 시 추천)

 

슬로우 쿼리 추적

logger.New(
  log.New(os.Stdout, "\r\n", log.LstdFlags),
  logger.Config{
    SlowThreshold: time.Second,
    LogLevel:      logger.Warn,
    Colorful:      true,
  },
)

 

 

 


 

 

5. 실전 예제: 유저 있으면 업데이트, 없으면 에러

 

user := User{}
err := db.First(&user, "email = ?", "hi@openai.com").Error
if errors.Is(err, gorm.ErrRecordNotFound) {
    return fmt.Errorf("유저가 존재하지 않습니다")
}

user.Name = "Updated Name"
if err := db.Save(&user).Error; err != nil {
    return fmt.Errorf("업데이트 실패: %w", err)
}

 

→ 에러와 없는 케이스를 명확히 구분!

 

 


 

6. 디버깅 & 에러 핸들링 꿀팁 요약

 

상황 대응 방법
데이터 없음 RowsAffected == 0 또는 gorm.ErrRecordNotFound
쿼리 디버깅 logger.Info 레벨 설정
슬로우 쿼리 추적 SlowThreshold 설정
GORM 에러 커스터마이징 errors.Is, errors.As 사용
다중 조건 복잡 로직 분기 처리 err != nil 체크 후 로깅 or 래핑 (fmt.Errorf)

 

 

 

 

 


 

🔚 마무리


GORM은 무조건 if err != nil만 반복하면 에러 흐름 파악이 어렵다.
RowsAffected, 에러 타입 분기, SQL 추적 설정만 잘 써도
디버깅 속도와 코드 안정성은 압도적으로 향상된다.

 

 

 

 

 

728x90