9

エラーを「再スロー」しrecoverて、元のスタック トレースを保持することは可能ですか? 私が知っている最善の方法は、再びパニックに陥ることですが、それによって新しいスタックトレースが作成されます。

func do() {
    defer func() {
        cleanUp()
        if x := recover(); x != nil {
            handleError()
            panic(x)
        }
    }()
    doStuff()
}

これを望む動機は、関数が正常に終了するかhandleError実行されない限り、プログラムがデッドロックすることです。そして、元のストラックの痕跡を保存しない限り、どこでクラッシュしたのかわかりません。

4

3 に答える 3

12

解決策は、 を呼び出さrecoverないことです。再スローすることも、スタック トレースにアクセスすることもできないためです。recoverパニックをチェックする代わりに bool フラグを使用します。

https://play.golang.org/p/PKeP9s-3tF

func do() {
    panicked := true
    defer func() {
        cleanUp()
        if panicked {
            handleError()
        }
    }()
    doStuff()
    panicked = false
}
于 2016-01-18T09:23:50.003 に答える
6

スタックの上位にある据え置き関数は、たとえ を呼び出さなくても、パニックで実行されますrecover()

if ステートメントと re-panic を削除するだけです。次に、エラーを処理し、パニックがスタックに続くようにします。

func do() {
    defer handleError()
    doStuff()
}

簡単なデモ:

https://play.golang.org/p/UiRou5MhUR

func a() {
    defer func() {
        fmt.Println("a")
    }()
    panic("test")
}
func b() {
    defer func() {
        fmt.Println("b")
    }()
}

func main() {
    fmt.Println("Hello, playground")
    b()
}

出力

Hello, playground
b
于 2016-01-17T20:11:12.247 に答える