2016-08-24 12 views
2

goエラー処理のほとんどの例では、エラーをスタックに戻すだけです。ある時点では、これらは解釈が必要であり、これが私がやろうとしていることです。 ここに私の試みの抜粋です:これは私の現在のケースのためにかかわらず、機能していないGolangの解釈エラーコード

resp, err := http.Get(string(url)) 
    defer out_count.Dec() 

    if err != nil { 

      switch err { 
      case http.ErrBodyReadAfterClose: 
        fmt.Println("Read after close error") 
      case http.ErrMissingFile: 
        fmt.Println("Missing File") 
      {some more cases here} 
      case io.EOF: 
        fmt.Println("EOF error found") 
      default: 
        fmt.Printf("Error type is %T\n", err) 
        panic(err) 
      } 
      return 

が(} URLを削除するように編集:

ERROR: Failed to crawl "http://{removed URL}" 
Error type is *url.Error 
panic: Get http://{removed url}: EOF 

goroutine 658 [running]: 
runtime.panic(0x201868, 0x106352c0) 
     /usr/lib/go/src/pkg/runtime/panic.c:279 +0x1a0 
github.com/cbehopkins/grab/grab.crawl(0x10606210, 0x27, 0x105184b0, 0x105184e0, 0x10500460) 

私が取得する方法を把握することはできませんswitch文は、エラーのテキストが毎回変更され、私が捕まえることができる明示的な値がないので、このエラーをキャッチするようにしてください(URLが常に変わるので)case文で正規表現のマッチングを行うか、エラー文字列をサブスライスするが、これはこの問題を解決するための非常に悪い方法のように感じる。

提案がありますか?このようなエラーを確実に捕まえるには、慣用的な方法が必要ですか?

答えて

3

最も簡単な方法は、あなたのコード内のパッケージ・レベルのエラー値を持っているだろう:

var URLFetchError = errors.New("Cannot fetch URL") 

url := "http://www.google.com" 
res, err := http.Get(url) 
if err != nil { 
    return URLFetchError 
} 

switchその後、次のようになります。

switch err { 
case http.ErrBodyReadAfterClose: 
    fmt.Println("Read after close error") 
case URLFetchError: 
    fmt.Println("Error fetching URL") 

あなたがより多くの情報を渡す場合エラー、独自のカスタムエラーを作成することができます:

type MyError struct { 
    URL string 
} 

func (e MyError) Error() string { 
    return fmt.Sprintf("Error getting: %v", e.URL) 
} 

その後、必要に応じてこのエラーを作成できます。あなたが定期的にミックスを持っているので、あなたのケースでは

switch err.(type) { 
case MyError: 
    fmt.Println("Error:", err) 
default: 
    fmt.Println("No Error") 
} 

:たとえば:

url := "http://www.google.com" 
res, err := http.Get(url) 
if err != nil { 
    return MyError{url} 
} 

最後に、あなたはタイプを使用することができますあなたのエラーチェックの方法でエラーを取得する代わりに、単純なスイッチの切り替えエラーは、ネストされたswitchでこのチェックを含めることができます。私のコードを扱うことができないエラーが発生した場合、私は、コードを停止するため

switch err { 
case http.ErrBodyReadAfterClose: 
    fmt.Println("Read after close error") 
case http.ErrMissingFile: 
    fmt.Println("Missing File") 
case io.EOF: 
    fmt.Println("EOF error found") 
default: // check for custom errors 
    switch err.(type) { 
    case MyError: 
     fmt.Println("custom error:", err) 
    default: 
     panic(err) 
    } 
} 
+0

徹底的な答えをありがとう! 私は、問題は、私は標準的なHTMLパッケージを取得しているエラーは私が一致することができます定義これらのエラーを提供していないということだと思う。 しかし、誤りの種類を最初に、次にエラーの詳細については後で切り替えることができます。 これで十分ですが、この要求を標準のhtmlパッケージに戻す方法を理解する必要があります。 ありがとう –

1

エラーインターフェイスを実装して、独自のエラーを作成して対処しやすくなります。

実行時エラーa.k.aパニック。パニックに思える機能にrecover()を含めることでリカバリーできます。これは、関数が返る前に呼び出されます。

defer func() { 
    if r := recover(); r != nil { 
     if _, ok := r.(runtime.Error); ok { 
       err = r.(error) //panic(r) 
      } 
      err = r.(error) 
     } 
    }() 
} 
+0

ああ、私はあなたが誤解していると考え、パニックがあります。それは私が私が必要とするすべての問題をキャッチしていないと言うデバッグのウィットを提供します。 ありがとうございました –

+0

おそらく、「エラーインターフェイスを実装する」とは、あなたが選んだ答えが何を意味するのか理解できませんでした。 – Sridhar