英文:
How to handle panic outside
问题
请看下面的代码片段。
package main
import "fmt"
func explode() {
// 引发 panic。
panic("WRONG")
}
func recovery() int {
explode()
defer func() {
fmt.Println("尝试处理 panic")
if err := recover(); err != nil {
fmt.Println("修复")
fmt.Println("错误", err)
}
}()
fmt.Println("打印值")
return 100
}
func main() {
// 使用 recover 在 defer 函数中处理错误。
fmt.Println(recovery())
}
如你所见,我在 explode
函数中引发了一个 panic,并希望在 recovery
函数中处理它。但是 panic 没有被捕获,我得到了运行时错误。
goroutine 1 [running]:
main.explode()
D:/gocode/src/samples/panic1.go:7 +0x6b
main.recovery(0xc082002250)
D:/gocode/src/samples/panic1.go:18 +0x26
main.main()
D:/gocode/src/samples/panic1.go:27 +0x26
goroutine 2 [runnable]:
runtime.forcegchelper()
c:/go/src/runtime/proc.go:90
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:2232 +0x1
goroutine 3 [runnable]:
runtime.bgsweep()
c:/go/src/runtime/mgc0.go:82
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:2232 +0x1
goroutine 4 [runnable]:
runtime.runfinq()
c:/go/src/runtime/malloc.go:712
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:2232 +0x1
exit status 2
如何在 recovery
函数中捕获 panic?
英文:
Look at the following code snippet.
package main
import "fmt"
func explode() {
// Cause a panic.
panic("WRONG")
}
func recovery() int {
explode()
defer func() {
fmt.Println("Try to handle panic")
if err := recover(); err != nil {
fmt.Println("FIX")
fmt.Println("ERR", err)
}
}()
fmt.Println("Print value")
return 100
}
func main() {
// Handle errors in defer func with recover.
fmt.Println(recovery())
}
As you can see code above, I fired a panic in the explode function and want to handle it in the recovery function. But the panic does not get caught, I've got runtime error
goroutine 1 [running]:
main.explode()
D:/gocode/src/samples/panic1.go:7 +0x6b
main.recovery(0xc082002250)
D:/gocode/src/samples/panic1.go:18 +0x26
main.main()
D:/gocode/src/samples/panic1.go:27 +0x26
goroutine 2 [runnable]:
runtime.forcegchelper()
c:/go/src/runtime/proc.go:90
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:2232 +0x1
goroutine 3 [runnable]:
runtime.bgsweep()
c:/go/src/runtime/mgc0.go:82
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:2232 +0x1
goroutine 4 [runnable]:
runtime.runfinq()
c:/go/src/runtime/malloc.go:712
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:2232 +0x1
exit status 2
How to catch the panic in the recory function?
答案1
得分: 6
如果你首先调用explode()
函数,处理panic
并尝试恢复的函数尚未注册(并且永远不会注册,因为你在explode()
函数内部调用了panic
),所以它不会被调用,显然它无法完成其工作。
你需要先调用defer
,然后再调用explode()
函数:
defer func() {
// 在这里进行recover(),你的代码被省略了
}()
explode()
在Go Playground上尝试一下。
英文:
If you call explode()
first, the function that would handle the panic
and try to recover is not yet registered (and never will be because you call panic
inside explode()
), so it won't be called and obviously it can't do its work.
You have to call defer
first and then the explode()
function:
defer func() {
// recover() here, Your code omitted
}()
explode()
Try it on the Go Playground.
答案2
得分: 0
对于更多的情况,"panic"只能在同一个例程中被"recover",不能在外部被恢复。
https://play.golang.org/p/e7-3SU2Cvss
英文:
for something more, "panic" could only be "recover" within the same routine, it couldn't be recovered outside.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论