정상우
hELLO.
정상우
전체 방문자
428,194
오늘
409
어제
688
  • hELLO. (122)
    • 컴퓨터과학 (4)
      • 알고리즘 & 자료구조 (4)
    • 언어 & 프레임워크 (63)
      • Go (23)
      • PHP & Laravel (40)
    • 웹 (7)
    • 블록체인 (12)
      • 메인넷 (9)
      • 암호화폐 플랫폼 (3)
    • 포트폴리오 (10)
    • 칼럼 (21)
      • 에세이 (4)
      • 개발자스럽게 살기 (15)
      • 회고 (2)
    • 티스토리 (5)

블로그 메뉴

  • ⚡ 개발자 이력서
  • 🌟 깃허브
  • 💻 강의
  • ✨ 예제코드
  • ⭐ 브런치
  • 태그 클라우드
  • 방명록

공지사항

  • 2차 도메인을 설정했습니다 ✨

인기 글

  • JWT(JSON Web Token)의 개념부⋯
    2021.07.29
    JWT(JSON Web Token)의 개념부⋯
  • 'REST' 를 보다 'RESTful' 하게⋯
    2021.08.14
    'REST' 를 보다 'RESTful' 하게⋯
  • [Laravel] 라라벨 프레임워크⋯
    2021.06.10
    [Laravel] 라라벨 프레임워크⋯
  • 깃허브를 포트폴리오로 쓰려면⋯
    2021.12.25
    깃허브를 포트폴리오로 쓰려면⋯
  • 암호화폐 트레이딩 봇을 만들었⋯
    2021.05.12
    암호화폐 트레이딩 봇을 만들었⋯

태그

  • 블록체인
  • 라라벨
  • 개발
  • go
  • 프로그래머스
  • php
  • 포트폴리오
  • 개발 리뷰
  • 코딩테스트
  • Algorithm

최근 댓글

  • 헉 ㅋㅋㅋㅋㅋㅋ 대학에서 잠깐⋯
    정상우
  • 오히려 반대인 경우도 있더라고⋯
    비스카이비전
  • 아무래도 후자가 많은 것 같긴⋯
    정상우
  • 조금 다른 이야기이긴 한데 좋⋯
    비스카이비전
  • 너무나 이쁘고 멋진 스킨 갑사⋯
    TerianP

최근 글

  • 기술적 가스라이팅은 이제 멈춰⋯
    2022.08.08
    기술적 가스라이팅은 이제 멈춰⋯
  • 빠르게 성장하는 개발자의 세⋯
    2022.06.08
    빠르게 성장하는 개발자의 세⋯
  • 개발자와 엔지니어, 그 사이에서
    2022.05.10
    개발자와 엔지니어, 그 사이에서
  • 아임포트(Iamport)로 결제기능⋯
    2022.04.03
    아임포트(Iamport)로 결제기능⋯
  • 아임포트(Iamport)로 결제기능⋯
    2022.04.01
    아임포트(Iamport)로 결제기능⋯

티스토리

hELLO · Designed By 정상우.
정상우

hELLO.

언어 & 프레임워크/Go

Go: 에러와 패닉 (panic, recover)

2020. 12. 5. 17:19

예외가 없다고?

그렇다. Go 언어에는 예외(Exception)가 없다. 에러로 모든 것을 처리한다. error 빌트인 타입은 존재하긴 하지만, 그렇다고 타언어처럼 모든 에러에 대해 타입이 매핑되어 있는 것은 아니다. 내가 접한 언어 중에는 Syntax, Out of Range 등을 전부 나눠놓은 경우가 있었는데, 그다지 좋은 기분이 들지는 않았다.

 

아니면 에러와 예외를 둘 다 사용하여 컴파일이나 정적으로 발생하는 것은 에러로, 런타임 중에 발생한 것은 예외로 하여 개별 클래스가 계층에 따라 분리된 경우도 있었는데, 상당히 헷갈리기 그지 없었다.

 

Go 에는 에러와 패닉이 있는데, 패닉은 런타임 중에 발생하는 치명적인 에러를 의미하며 프로그램이 더 이상 진행될 수 없는 수준의 에러다. 상당히 치명적이어서 패닉이 발생하면 프로그램이 종료된다. 반면 일반적인 에러로는 프로그램이 종료되지 않는다. 패닉은 일반적으로 개발자가 미처 대처하지 못한 알려지지 않은 예외에 대해 적용된다.

에러

일반적인 에러는 발생해도 프로그램이 종료되지 않는다. 예를 들어 아래와 같이 파일을 열 때, 에러도 반환하는데, 일반적으로는 아래와 같이 처리한다. 조건문을 사용하고 에러가 nil 이 아닌지 검사하는 것이다. 일반적으로 에러가 발생하면 err 에 nil 이 아닌 error 타입의 값이 할당된다.

package main

import (
	"log"
	"os"
)

func main() {
	_, err := os.Open("Unknown.txt")
	if err != nil {
		log.Fatal(err)
	}
}

error interface

error 는 빌트인 타입, 정확히 말하자면 인터페이스다. Error() 메서드를 구현한 구조체라면 error 타입으로 활용이 가능하다. error 인터페이스를 구현하게 되면 나만의 에러를 만드는 것도 어려운 일이 아니다.

$ go doc builtin error
package builtin // import "builtin"

type error interface {
        Error() string
}
    The error built-in interface type is the conventional interface for
    representing an error condition, with the nil value representing no error.

패닉

패닉은 런타임 중에 발생한 치명적인 에러다. 아래의 코드는 배열에서 인덱스를 넘은 값에 접근하려고 하자 발생한 패닉이다. 에러는 처리해줄 수도 있고 안 해줄 수도 있지만, 일반적인 경우라는 패닉은 발생하는 일이 없어야한다. 알려지지 않은 경우에 대해 발생하는 패닉은 아래에서 나오는 방법으로 어느정도 제어가 가능하다.

package main

import "fmt"

func main() {
	var numbers [1]int
	for i := 0; i <= len(numbers); i++ {
		// -> panic: runtime error: index out of range [1] with length 1
		fmt.Println(numbers[i])
	}
}

panic()

타언어에서 예외를 던지듯이 패닉또한 개발자가 패닉이 필요하다고 느끼는 시점에서 빌트인 함수인 panic() 함수를 통해 던질 수 있다. 패닉이 발생하면 현재 실행중인 고루틴을 멈춘다. 또한 패닉에서 중요한 점은 패닉이 발생해도 defer 를 통해 예약해둔 함수는 호출이 보장된다는 점이다.

package main

import "fmt"

func main() {
	defer fmt.Println("Hello, Go!")
	// -> panic: PANIC
	panic("PANIC")
}

여기서 주의해야 할 점은, 패닉이 발생한 시점에서 즉시 멈추기 때문에 panic() 함수 이후에 있는 구문은 실행되지 않는다는 점이다.

recover()

recover() 함수를 사용하면 패닉이 발생해도 회복이 가능하다. 위에서 defer 를 통해 함수를 예약해두면 패닉이 발생해도 실행을 해준다고 했다. defer 에 recover() 가 포함되어있는 함수를 호출하게 되면 패닉을 정상적인 상태로 되돌릴 수 있다. 이렇게 패닉을 회복하고, recover() 함수는 패닉을 호출할 때 넘겨준 파라매터를 리턴값으로 되돌려준다. 만약 패닉이 발생하지 않았다면 리턴 값은 nil 이다.

package main

import "fmt"

func main() {
	defer func() {
		// -> PANIC
		fmt.Println(recover())
	}()
	panic("PANIC")
}

recover() 를 통하면 발생하는 모든 패닉에 대해서는 유연하게 대처할 수 있겠으나, 정말로 예상하지 못한 에러에 대해서는 패닉을 제대로 발생시켜줄 필요가 있다. 따라서 패닉을 한 번 더 쓰는것도 좋다.

package main

import (
	"errors"
	"fmt"
)

func main() {
	defer func() {
		p := recover()
		if p == nil {
			return
		}
		err, ok := p.(error)
		if ok {
			fmt.Printf("%#v\n", err)
			return
		}
		panic(p)
	}()
	panic(errors.New("ERROR"))
}
    '언어 & 프레임워크/Go' 카테고리의 다른 글
    • Go: Go 답게 코드 작성하기
    • Go: 고루틴과 채널 (go-routine, chan)
    • Go: 인터페이스와 타입 단언 (Interface, Type Assertion)
    • Go: 구조체 (메서드, 임베딩, 캡슐화)
    error, go, Panic, recover, 에러, 예외, 패닉
    정상우
    정상우
    과거의 배움으로 현재를 바꾸고 미래를 만듭니다. #25+2살 #INFJ #개발자 #브런치작가
    댓글쓰기
    다음 글
    Go: 고루틴과 채널 (go-routine, chan)
    이전 글
    Go: 인터페이스와 타입 단언 (Interface, Type Assertion)
    • 이전
    • 1
    • ···
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • ···
    • 122
    • 다음

    티스토리툴바