[error-handling] 방금 호출 한 오류의 줄 번호를 인쇄하는 Golang 프로그램을 어떻게 얻습니까?

내 Golang 프로그램에서 오류를 던지려고 log.Fatal했지만 실행 된 log.Fatal줄도 인쇄하지 않습니다 log.Fatal. log.Fatal을 호출 한 줄 번호에 액세스 할 수있는 방법이 없습니까? 즉, 오류를 던질 때 줄 번호를 얻는 방법이 있습니까?

나는 이것을 구글로 시도했지만 방법을 확신하지 못했습니다. 내가 얻을 수있는 가장 좋은 방법 은 스택 트레이스를 인쇄하는 것이 었는데 , 이것은 좋지만 너무 많을 수 있습니다. 나는 또한 debug.PrintStack()줄 번호가 필요할 때마다 쓰고 싶지 않습니다. 이와 같은 기능 log.FatalStackTrace()이나 의상이 아닌 것에 대한 내장 기능이 없다는 것에 놀랐습니다 .

또한, 내가 직접 디버깅 / 오류 처리를하고 싶지 않은 이유는 사람들이 내 특별한 의상 처리 코드를 사용하는 방법을 배우지 않기를 원하기 때문입니다. 나는 사람들이 나중에 내 코드를 읽고

“아 좋아, 그래서 오류가 발생하고 X를 수행하는 중 …”

사람들이 내 코드에 대해 배울수록 더 좋습니다. 🙂



답변

사용자 정의 로거에서 플래그를 설정하거나 기본값을 포함 Llongfile하거나Lshortfile

// to change the flags on the default logger
log.SetFlags(log.LstdFlags | log.Lshortfile)


답변

짧은 버전, 직접 내장 된 것은 없습니다그러나 다음을 사용하여 최소한의 학습 곡선으로 구현할 수 있습니다. runtime.Caller

func HandleError(err error) (b bool) {
    if err != nil {
        // notice that we're using 1, so it will actually log where
        // the error happened, 0 = this function, we don't want that.
        _, fn, line, _ := runtime.Caller(1)
        log.Printf("[error] %s:%d %v", fn, line, err)
        b = true
    }
    return
}

//this logs the function name as well.
func FancyHandleError(err error) (b bool) {
    if err != nil {
        // notice that we're using 1, so it will actually log the where
        // the error happened, 0 = this function, we don't want that.
        pc, fn, line, _ := runtime.Caller(1)

        log.Printf("[error] in %s[%s:%d] %v", runtime.FuncForPC(pc).Name(), fn, line, err)
        b = true
    }
    return
}

func main() {
    if FancyHandleError(fmt.Errorf("it's the end of the world")) {
        log.Print("stuff")
    }
}

playground


답변

정확히 스택 추적이 필요한 경우 https://github.com/ztrue/tracerr를 살펴보십시오.

이 패키지는 스택 추적과 소스 조각을 모두 더 빠르게 디버깅하고 훨씬 더 자세한 내용으로 오류를 기록 할 수 있도록 만들었습니다.

다음은 코드 예입니다.

package main

import (
    "io/ioutil"
    "github.com/ztrue/tracerr"
)

func main() {
    if err := read(); err != nil {
        tracerr.PrintSourceColor(err)
    }
}

func read() error {
    return readNonExistent()
}

func readNonExistent() error {
    _, err := ioutil.ReadFile("/tmp/non_existent_file")
    // Add stack trace to existing error, no matter if it's nil.
    return tracerr.Wrap(err)
}

다음은 출력입니다.
golang 오류 스택 추적


답변