더북(TheBook)

6.3.2 recover

recover() 함수는 패니킹 작업으로부터 프로그램의 제어권을 다시 얻어 종료 절차를 중지시키고 프로그램을 계속 이어갈 수 있게 한다.

recover()는 반드시 defer 안에서 사용해야 한다. defer 구문 안에서 recover()를 호출하면 패닉 내부의 상황을 error 값으로 복원할 수 있다. recover()로 패닉을 복원한 후에는 패니킹 상황이 종료되고 함수 반환 타입의 제로값이 반환된다.


func main() {
    fmt.Println("result: ", divide(1, 0))
}
 
func divide(a, b int) int {
    defer func() {
        if err := recover(); err != nil {
            fmt.Println(err)
        }
    }()
    return a / b
}

실행 결과

runtime error: integer divide by zero

result: 0

이는 자바나 .Net의 try-catch 블록과 유사하다.

다음 protect() 함수는 매개변수로 받은 함수 g를 호출한다. 만약 g에서 패닉이 발생하면 패닉에서 error 정보를 가져와 출력한다.


func protect(g func()) {
    defer func() {
        log.Println("done")
 
        if err := recover(); err != nil {
            log.Printf("run time panic: %v", err)
        }
    }()
    log.Println("start")
    g()
}
 
func main() {
    protect(func() {
        fmt.Println(divide(4, 0))
    })
}
 
func divide(a, b int) int {
    return a / b
}

실행 결과

start

done

run time panic: runtime error: integer divide by zero

이처럼 protect() 함수에 코드 블록을 클로저로 만들어 넘기면 예상치 못한 패닉에 의해 프로그램이 비정상적으로 종료되는 것을 막을 수 있다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.