에러 처리하기



이재홍 http://www.pyrasis.com 2014.12.17 ~ 2015.02.07



에러 타입 만들기

에러 타입은 에러를 확장하여 좀 더 자세한 에러 내용을 저장하기 위해 사용합니다. 이번에는 에러 타입을 직접 만들어보겠습니다.

package main

import (
	"fmt"
	"log"
	"time"
)

type HelloOneError struct {
	time  time.Time // 시간
	value int       // 에러를 발생시킨 값
}

func (e HelloOneError) Error() string { // 에러 메시지를 생성하여 리턴하는 Error 함수 구현
	return fmt.Sprintf("%v: %d는 1이 아닙니다.", e.time, e.value)
}

func helloOne(n int) (string, error) {
	if n == 1 {                           // 1일때만
		s := fmt.Sprintln("Hello", n) // Hello 문자열을 리턴
		return s, nil                 // 정상 동작이므로 에러 값은 nil
	}

	return "", HelloOneError{time.Now(), n} // 1이 아닐때는 에러 구조체 인스턴스를
                                                // 생성하여 리턴
}

func main() {
	s, err := helloOne(1) // 매개변수에 1을 넣었으므로 정상 동작
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(s) // Hello 1

	s, err = helloOne(2)   // 매개변수에 2를 넣었으므로 에러 발생
	if err != nil {
		log.Fatal(err) // 에러 문자열이 출력되고 프로그램 종료
	}

	// 에러가 발생하여 프로그램이 종료되었으므로 이 아래부터는 실행되지 않음
	fmt.Println(s)

	fmt.Println("Hello, world!")
}

error 타입이 아니더라도 Error 함수를 구현하면 에러로 사용할 수 있습니다.

type HelloOneError struct {
	time  time.Time // 시간
	value int       // 에러를 발생시킨 값
}

func (e HelloOneError) Error() string { // 에러 메시지를 생성하여 리턴하는 Error 함수 구현
	return fmt.Sprintf("%v: %d는 1이 아닙니다.", e.time, e.value)
}

HelloOneError 구조체에는 시간과 에러를 발생시킨 값을 저장할 수 있습니다. 그리고 Error 함수는 에러 메시지 생성하여 리턴합니다.

helloOne 함수에서는 에러가 발생했을 때 HelloOneError 구조체를 생성하여 리턴합니다. 현재 시간은 time.Now 함수로 구할 수 있습니다.

func helloOne(n int) (string, error) {
	if n == 1 {                           // 1일때만
		s := fmt.Sprintln("Hello", n) // Hello 문자열을 리턴
		return s, nil                 // 정상 동작이므로 에러 값은 nil
	}

	return "", HelloOneError{time.Now(), n} // 1이 아닐때는 에러 구조체 인스턴스를
                                                // 생성하여 리턴
}

출력 결과를 보면 Error 함수에서 만든 에러 메시지가 출력됩니다.

실행 결과

Hello 1

2015/01/25 13:14:59 2015-01-25 13:14:59.3055342 +0900 KST: 2는 1이 아닙니다.

error 타입으로 리턴된 HelloOneError 구조체는 다음과 같이 Type assertion을 해주면 구조체 필드에 접근할 수 있습니다.

s, err = helloOne(2)
if err != nil {
	fmt.Println(err.(HelloOneError).value) // 2: Type assertion으로 구조체 필드에 접근
}

저작권 안내

이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.
  • 블로그, 게시판 등에 퍼가는 것을 금지합니다.
  • 비공개 포스트에 퍼가는 것을 금지합니다.
  • 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
  • 링크 및 SNS 공유는 허용합니다.

Published

01 June 2015