2016-01-16 57 views
0

它看起来不可能从恐慌中的恐慌中恢复过来吗?是否有可能从恐慌中的恐慌中恢复过来?

func TestError(t *testing.T) { 

    e := &myErr{p: false} 
    fmt.Println(e.Error()) // this prints "returned" 
    panic(e)    // this prints "panic: returned" 

    e1 := &myErr{p: true} 
    fmt.Println(e1.Error()) // this prints "recovered" 
    panic(e1)    // this prints "panic: panic: paniced 
          //    fatal error: panic holding locks 
          //    panic during panic" 
} 

type myErr struct { 
    p bool 
} 

func (m *myErr) Error() (out string) { 
    defer func() { 
     if r := recover(); r != nil { 
      out = "recovered" 
     } 
    }() 
    if m.p { 
     panic("paniced") 
    } 
    return "returned" 
} 

背景故事:我的错误错误()函数使用os.Getwd,这似乎总是在恐慌中恐慌,所以我想优雅地处理这个问题。

+1

你为什么首先恐慌?你是否试图用恐慌作为例外机制?正如你所看到的,你不应该做任何可能在尝试恢复时也会恐慌的事情。 – JimB

+0

我绝对不会使用恐慌。在我的使用中,恐慌只会因程序员错误而发生,而不是用户错误。 –

+0

嗯,我不确定现在“测试”软件包有什么不同。试着弄清楚如何复制这个作为一个独立的例子,看看它是否是一个bug。 – JimB

回答

0

我认为它解决您的问题,通过这个

panic(e1.Error()) 

游乐场替换此

panic(e1) 

http://play.golang.org/p/fXpX2ch9eF

而且问题在这里有趣的是:为什么呢?这是困难的部分,我不知道确切的答案。恐怕这里的问题是,我们在执行所有的被执行的函数后进行panicing(所以当Go尝试打印恐慌错误字符串时)。如果不正确,欢迎任何更正!

+0

是的,这是我解决的解决方法,但我想更完整地解释它为什么不起作用... –