PHpullh
학습 라이브러리/Go/에러 처리 패턴 & errors 패키지

GO · 에러처리

에러 처리 패턴 & errors 패키지

Go의 에러 처리 철학: 에러는 값입니다. 예외 대신 명시적 반환으로 처리합니다.

에러처리입문errorerrors.Iserrors.Asfmt.Errorf%w

핵심 설명

Go의 에러 처리 철학: 에러는 값입니다. 예외 대신 명시적 반환으로 처리합니다.

Go code

package main

import (
	"errors"
	"fmt"
)

// Sentinel error — 비교 가능한 에러 값
var (
	ErrNotFound   = errors.New("not found")
	ErrPermission = errors.New("permission denied")
)

// 커스텀 에러 타입
type NotFoundError struct {
	Resource string
	ID       int
}

func (e *NotFoundError) Error() string {
	return fmt.Sprintf("%s #%d를 찾을 수 없습니다", e.Resource, e.ID)
}

// 에러 래핑 (Go 1.13+)
func findUser(id int) (string, error) {
	if id <= 0 {
		return "", fmt.Errorf("잘못된 ID %d: %w", id, ErrNotFound)
	}
	if id > 100 {
		return "", &NotFoundError{"User", id}
	}
	return fmt.Sprintf("User#%d", id), nil
}

func main() {
	// 기본 에러 처리
	user, err := findUser(0)
	if err != nil {
		// errors.Is — Sentinel 에러 체인 검사
		if errors.Is(err, ErrNotFound) {
			fmt.Println("없음:", err)
		}
	} else {
		fmt.Println(user)
	}

	// errors.As — 특정 타입으로 언래핑
	_, err = findUser(999)
	var nfe *NotFoundError
	if errors.As(err, &nfe) {
		fmt.Printf("리소스: %s, ID: %d
", nfe.Resource, nfe.ID)
	}

	// 에러 무시 안 하기
	if _, err := findUser(1); err != nil {
		fmt.Println("예상치 못한 에러:", err)
	} else {
		fmt.Println("성공!")
	}

	// fmt.Errorf + %w로 컨텍스트 추가
	err = fmt.Errorf("서비스 레이어: %w",
		fmt.Errorf("저장소 레이어: %w", ErrNotFound))
	fmt.Println(err)
	fmt.Println(errors.Is(err, ErrNotFound)) // true (체인 탐색)
}

학습 팁

errors.Is()는 에러 체인을 재귀적으로 탐색합니다. %w로 래핑된 에러도 감지합니다. 단순 == 비교보다 항상 errors.Is()를 사용하세요.

주의할 점

if err != nil { return err }를 반복하는 것은 Go의 정상적인 패턴입니다. 에러를 무시하거나 _로 버리지 마세요.

자주 묻는 질문

에러 처리 패턴 & errors 패키지란 무엇인가요?

Go의 에러 처리 철학: 에러는 값입니다. 예외 대신 명시적 반환으로 처리합니다.

에러 처리 패턴 & errors 패키지 학습 시 주의할 점은 무엇인가요?

if err != nil { return err } 를 반복하는 것은 Go의 정상적인 패턴입니다. 에러를 무시하거나 _ 로 버리지 마세요.