Menu
Coddy logo textTech

%w를 사용한 에러 래핑

Coddy GO 여정의 로직 & 흐름 섹션에 포함된 레슨 — 68개 중 39번째.

애플리케이션에서 오류가 발생하면, 코드의 여러 계층을 거쳐 올라가면서 추가적인 컨텍스트가 필요한 경우가 많습니다. Go는 fmt.Errorf와 함께 %w 형식 지정자를 사용하는 에러 래핑(error wrapping)을 통해 이를 위한 강력한 메커니즘을 제공합니다.

에러 래핑(Error wrapping)을 사용하면 원래의 에러를 유지하면서 기존 에러에 문맥 정보를 추가할 수 있습니다. 이를 통해 무엇이 잘못되었는지에 대한 전체 이력을 유지하는 에러 체인이 생성됩니다:

originalErr := errors.New("file not found")
wrappedErr := fmt.Errorf("failed to load config: %w", originalErr)

%w 동사는 특별합니다. 이것은 fmt.Errorf가 에러를 단순히 문자열로 변환하는 대신 래핑(wrap)하도록 지시합니다. 이를 통해 원본 에러가 보존되므로 나중에 errors.Iserrors.As와 같은 함수를 사용하여 검사할 수 있습니다.

이 패턴은 오류가 여러 함수를 거치면서 각 함수가 고유한 컨텍스트를 추가할 수 있는 대규모 애플리케이션에서 특히 유용합니다. 예를 들어, 데이터베이스 연결 오류가 "failed to connect to database"로 감싸지고, 다시 "unable to start server"로 감싸져서 무엇이 어디서 일어났는지에 대한 명확한 추적 경로를 생성할 수 있습니다.

quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

challenge icon

챌린지

쉬움

애플리케이션의 여러 레이어를 거쳐 전파될 때 컨텍스트 정보와 함께 에러를 래핑하는 파일 처리 시스템을 구축하세요. 이 챌린지는 fmt.Errorf%w 포맷 동사를 사용하여 의미 있는 컨텍스트를 추가하면서도 원본 에러를 보존하는 에러 체인을 만드는 방법을 보여줍니다.

두 개의 입력을 받게 됩니다:

  • "filename,operation,status" 형식의 파일 작업 세부 정보가 포함된 문자열 (예: "config.json,read,permission_denied")
  • "service_name,component" 형식의 시스템 컨텍스트가 포함된 문자열 (예: "UserService,ConfigLoader")

당신의 과제는 다음과 같습니다:

  1. 쉼표를 기준으로 첫 번째 입력을 파싱하여 filename, operation, status를 가져옵니다.
  2. 쉼표를 기준으로 두 번째 입력을 파싱하여 service name과 component를 가져옵니다.
  3. errors.New()를 사용하여 status에 따른 원본 에러를 생성합니다:
    • status가 "permission_denied"인 경우: "permission denied"
    • status가 "not_found"인 경우: "file not found"
    • status가 "corrupted"인 경우: "file corrupted"
    • 그 외의 모든 status: "unknown error"
  4. fmt.Errorf%w를 사용하여 파일 레벨의 래핑된 에러를 생성합니다: "failed to [operation] file [filename]: %w"
  5. 컴포넌트 레벨의 래핑된 에러를 생성합니다: "[component] error: %w"
  6. 서비스 레벨의 래핑된 에러를 생성합니다: "[service_name] operation failed: %w"
  7. 각 레벨을 출력하여 에러 체인을 표시합니다:
    • "Original error: [original_error_message]"
    • "File level: [file_level_error_message]"
    • "Component level: [component_level_error_message]"
    • "Service level: [service_level_error_message]"
  8. 에러 체인의 요약을 표시합니다:
    • "Error Chain Summary:"
    • "File: [filename]"
    • "Operation: [operation]"
    • "Component: [component]"
    • "Service: [service_name]"
    • "Root cause: [original_error_message]"

입력 문자열을 쉼표로 분리하기 위해 strings 패키지를 사용하고, 원본 에러를 생성하기 위해 errors 패키지를, 래핑된 에러를 생성하기 위해 fmt 패키지를 사용하세요. 이 챌린지는 %w를 사용한 에러 래핑이 에러가 애플리케이션의 서로 다른 레이어를 이동할 때 어떻게 명확한 컨텍스트 추적을 생성하여 디버깅을 훨씬 효과적으로 만드는지 보여줍니다.

치트 시트

에러 래핑(Error wrapping)을 사용하면 원본 에러를 보존하면서 기존 에러에 컨텍스트 정보를 추가할 수 있습니다. fmt.Errorf와 함께 %w 포맷 동사를 사용하세요:

originalErr := errors.New("file not found")
wrappedErr := fmt.Errorf("failed to load config: %w", originalErr)

%w 동사는 원본 에러를 보존하므로 나중에 errors.Iserrors.As와 같은 함수를 사용하여 검사할 수 있습니다. 이는 무엇이 잘못되었는지에 대한 전체 이력을 유지하는 에러 체인을 생성하며, 대규모 애플리케이션에서 에러가 여러 함수를 거칠 때 매우 유용합니다.

직접 해보기

package main

import (
	"errors"
	"fmt"
	"strings"
)

func main() {
	// 입력 읽기
	var fileDetails string
	var systemContext string
	fmt.Scanln(&fileDetails)
	fmt.Scanln(&systemContext)
	
	// 입력 파싱
	fileInfo := strings.Split(fileDetails, ",")
	filename := fileInfo[0]
	operation := fileInfo[1]
	status := fileInfo[2]
	
	contextInfo := strings.Split(systemContext, ",")
	serviceName := contextInfo[0]
	component := contextInfo[1]
	
	// TODO: 아래에 코드를 작성하세요
	// 상태에 따른 원본 에러 생성
	// 파일 수준의 래핑된 에러 생성
	// 컴포넌트 수준의 래핑된 에러 생성
	// 서비스 수준의 래핑된 에러 생성
	// 각 에러 수준 및 요약 출력
	
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

로직 & 흐름의 모든 레슨