检查是否发生了恐慌,但没有从中恢复。

huangapple go评论83阅读模式
英文:

Checking for panic without recovering from it

问题

在一个延迟函数中,我想要查看调用 recover 函数是否会返回一个非空值(而不进行恢复操作)。

这是否可能?

英文:

In a defer function, I want to see whether a call to recover would yield a non-nil value (without recovering)

Is it possible?

答案1

得分: 15

那个确切的事情是不可能的。你可能只是想重新引发恐慌,基本上就像在其他语言中重新抛出异常一样;

延迟函数() {
如果 e := recover(); e != nil {
//记录日志和其他操作
恐慌(e)
}
}()

英文:

That exact thing isn't possible. You probably just want to re-panic, basically like re-throwing an exception in other languages;

        defer func() {
             if e := recover(); e != nil {
                 //log and so other stuff
                 panic(e)
             }
          }()

答案2

得分: 4

你可以设置一个布尔标志,并在函数体的末尾将其重置。如果在延迟函数中标志仍然被设置,那么你就知道最后一条语句没有执行。唯一可能的原因是函数发生了恐慌。

func do() {
    panicking := true
    defer func() {
        if panicking {
            fmt.Println("recover would return !nil here")
        }
    }()

    doStuff()

    panicking = false
}

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

英文:

You can set a bool flag and then reset it at the end of the body of your function. If the flag is still set inside defer, you know that the last statement did not execute. The only possible reason for that is that the function is panicking.

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
}

答案3

得分: 0

解决方案没有“直接”路径

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)
}

请注意,这是您提供的代码的翻译版本。如果您有任何其他问题,请告诉我。

英文:

The solution does not have "direct" paths

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)
}

huangapple
  • 本文由 发表于 2015年5月6日 04:45:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/30062949.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定