2016-07-08 58 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