2016-07-08 28 views
2

Code Play Golang Link重试与相同参数的方法导致了它的恐慌

package main 

import "fmt" 

func test(i int){ 
    defer func(){ 
     if r := recover(); r != nil { 
      fmt.Println("Inside Recover: ", r) 
     } 

    }() 
    for try := 1 ; try <= i ; try++{ 
     if (i == 3){ 
      panic("Panic") 
     } 
     fmt.Printf("i: %d try: %d\n", i , try) 
    } 
} 

func main(){ 

    for i := 1 ; i < 5 ; i++{ 
     test(i) 
    } 
} 

的方法恐慌并跳至下一i价值,但不尝试i倍。有没有一种方法可以让我们从恐慌中恢复过来并重试相同的价值导致恐慌的i

+2

您可以将'i'传递给'panic',这是'recover'返回的内容。但是很可能您应该使用错误值。 go中的恐慌主要用于无法恢复的意外错误。 – kostya

+0

@kostya:我完全同意你使用错误值。我的问题是一些功能不完整,所以正在使用恐慌。我们只是想确保服务器不会崩溃并可用于处理下一个请求。 –

+0

你确定你必须使用恐慌吗?从你的代码似乎返回第二个错误参数 - godiomatic方式 - 更适合这种情况。仅供参考恐慌/恢复不是我们所说的其他语言的try/catch。错误是Go中的错误处理。如果程序恐慌,比如它没有访问数据库或文件系统(因此继续工作毫无意义)或某些其他外部(C)lib无法正常工作,则会使用恐慌。 –

回答

1

我假设你想测试任何可能会失败的函数,最好不必更改该函数。这里我的解决方案希望这是你正在寻找的。

Go PlayGround

package main 

import (
    "errors" 
    "fmt" 
) 

func test(i int) error { 
    if i == 3 { 
     return errors.New("Panic") 
    } 
    return nil 
} 

func retryWrapper(i, try int) { 
    err := test(i) 
    fmt.Printf("i: %d try: %d\n", i, try) 

    if err != nil && try < 5 { 
     retryWrapper(i, try+1) 
    } 
} 

func main() { 
    for i := 1; i < 5; i++ { 
     retryWrapper(i, 1) 
    } 
} 

这适用于返回错误的功能。如果你的函数恐慌,您将需要一个延迟改变测试功能/恢复这样的:

Recover Sample

func test(i int) (err error) { 
    defer func() { 
     if r := recover(); r != nil { 
      err = errors.New(r.(string)) 
     } 
    }() 
    if i == 3 { 
     panic("Panic") 
    } 
    return 
} 

注:重试限制为5名改掉,以防止无限循环。

+0

那么你建议在推迟恢复块我应该手动创建一个错误并返回它? –

+0

正确。并基于此从外部再次调用该函数。如果您尝试在推迟块中再次调用该函数,则必须使用附加参数更改该函数,以了解例如何时停止重试。 – TehSphinX