%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.Is 및 errors.As와 같은 함수를 사용하여 검사할 수 있습니다.
이 패턴은 오류가 여러 함수를 거치면서 각 함수가 고유한 컨텍스트를 추가할 수 있는 대규모 애플리케이션에서 특히 유용합니다. 예를 들어, 데이터베이스 연결 오류가 "failed to connect to database"로 감싸지고, 다시 "unable to start server"로 감싸져서 무엇이 어디서 일어났는지에 대한 명확한 추적 경로를 생성할 수 있습니다.
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
챌린지
쉬움애플리케이션의 여러 레이어를 거쳐 전파될 때 컨텍스트 정보와 함께 에러를 래핑하는 파일 처리 시스템을 구축하세요. 이 챌린지는 fmt.Errorf와 %w 포맷 동사를 사용하여 의미 있는 컨텍스트를 추가하면서도 원본 에러를 보존하는 에러 체인을 만드는 방법을 보여줍니다.
두 개의 입력을 받게 됩니다:
"filename,operation,status"형식의 파일 작업 세부 정보가 포함된 문자열 (예:"config.json,read,permission_denied")"service_name,component"형식의 시스템 컨텍스트가 포함된 문자열 (예:"UserService,ConfigLoader")
당신의 과제는 다음과 같습니다:
- 쉼표를 기준으로 첫 번째 입력을 파싱하여 filename, operation, status를 가져옵니다.
- 쉼표를 기준으로 두 번째 입력을 파싱하여 service name과 component를 가져옵니다.
errors.New()를 사용하여 status에 따른 원본 에러를 생성합니다:- status가
"permission_denied"인 경우:"permission denied" - status가
"not_found"인 경우:"file not found" - status가
"corrupted"인 경우:"file corrupted" - 그 외의 모든 status:
"unknown error"
- status가
fmt.Errorf와%w를 사용하여 파일 레벨의 래핑된 에러를 생성합니다:"failed to [operation] file [filename]: %w"- 컴포넌트 레벨의 래핑된 에러를 생성합니다:
"[component] error: %w" - 서비스 레벨의 래핑된 에러를 생성합니다:
"[service_name] operation failed: %w" - 각 레벨을 출력하여 에러 체인을 표시합니다:
"Original error: [original_error_message]""File level: [file_level_error_message]""Component level: [component_level_error_message]""Service level: [service_level_error_message]"
- 에러 체인의 요약을 표시합니다:
"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.Is 및 errors.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: 아래에 코드를 작성하세요
// 상태에 따른 원본 에러 생성
// 파일 수준의 래핑된 에러 생성
// 컴포넌트 수준의 래핑된 에러 생성
// 서비스 수준의 래핑된 에러 생성
// 각 에러 수준 및 요약 출력
}이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
로직 & 흐름의 모든 레슨
7에러 처리 심화
사용자 정의 에러 타입%w를 사용한 에러 래핑errors.Is를 사용한 언래핑errors.As를 사용한 언래핑panic 이해하기recover 사용하기요약 - 안전한 나눗셈