检查恐慌而不从中恢复
Checking for panic without recovering from it
在 defer 函数中,我想看看对 recover 的调用是否会产生一个非 nil 值(没有 recovery)
可能吗?
确切的事情是不可能的。你可能只是想重新恐慌,基本上就像在其他语言中重新抛出异常;
defer func() {
if e := recover(); e != nil {
//log and so other stuff
panic(e)
}
}()
您可以设置一个 bool 标志,然后在函数体的末尾重置它。如果在 defer 中仍然设置了标志,你就知道最后一条语句没有执行。唯一可能的原因是该函数出现恐慌。
https://play.golang.org/p/PKeP9s-3tF
func do() {
panicking := true
defer func() {
if panicking {
fmt.Println("recover would return !nil here")
}
}()
doStuff()
panicking = false
}
解决方案没有 "direct" 路径
package main
import(
"fmt"
"runtime"
"regexp"
)
var re_runtimepanicdetector *regexp.Regexp = regexp.MustCompile("runtime/panic.go$");
func tester_for_panic( deferdepth int )bool{
_,file,_,_ := runtime.Caller(deferdepth+3)
return re_runtimepanicdetector.MatchString(file)
}
func tester_for_panic_worktest() bool {
defer func(){
recover() ;
if !tester_for_panic(0) { panic("tester_for_panic: NOT WORK!!") }
}();
panic(1)
}
var Iswork_tester_for_panic bool= tester_for_panic_worktest();
func testp( dopanic bool ) {
defer func() {
fmt.Println("defer panic=", tester_for_panic(0)) ;
recover() // optional
}()
if (dopanic) { panic("test") }
}
func main(){
testp(true)
testp(false)
}
在 defer 函数中,我想看看对 recover 的调用是否会产生一个非 nil 值(没有 recovery)
可能吗?
确切的事情是不可能的。你可能只是想重新恐慌,基本上就像在其他语言中重新抛出异常;
defer func() {
if e := recover(); e != nil {
//log and so other stuff
panic(e)
}
}()
您可以设置一个 bool 标志,然后在函数体的末尾重置它。如果在 defer 中仍然设置了标志,你就知道最后一条语句没有执行。唯一可能的原因是该函数出现恐慌。
https://play.golang.org/p/PKeP9s-3tF
func do() {
panicking := true
defer func() {
if panicking {
fmt.Println("recover would return !nil here")
}
}()
doStuff()
panicking = false
}
解决方案没有 "direct" 路径
package main
import(
"fmt"
"runtime"
"regexp"
)
var re_runtimepanicdetector *regexp.Regexp = regexp.MustCompile("runtime/panic.go$");
func tester_for_panic( deferdepth int )bool{
_,file,_,_ := runtime.Caller(deferdepth+3)
return re_runtimepanicdetector.MatchString(file)
}
func tester_for_panic_worktest() bool {
defer func(){
recover() ;
if !tester_for_panic(0) { panic("tester_for_panic: NOT WORK!!") }
}();
panic(1)
}
var Iswork_tester_for_panic bool= tester_for_panic_worktest();
func testp( dopanic bool ) {
defer func() {
fmt.Println("defer panic=", tester_for_panic(0)) ;
recover() // optional
}()
if (dopanic) { panic("test") }
}
func main(){
testp(true)
testp(false)
}