2016-08-24 3 views
2

대부분의 오류 처리 오류는 스택 오류를 전달하는 것으로 볼 수 있습니다. 어느 시점에서 이것들은 해석이 필요하며 이것은 내가하려고하는 것입니다. 여기 내 시도의 조각입니다 : 이것은 내 현재 사건에 대한하지만 작동하지 않습니다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 문은 매번 오류 텍스트가 바뀌고 catch 할 수있는 명시적인 값이 없기 때문에이 오류를 잡을 수 있습니다 (URL이 항상 변경됨). 이제는 case 문에서 정규 표현식 일치를 수행 할 수 있습니다. 하위 슬라이스 오류 문자열,하지만이 문제를 해결할 수있는 아주 나쁜 방법을 느낀다.

제안 사항이 있으십니까? 이 같은 오류를 잡는 관용적 인 방법이 틀림없이 있어야합니까?

답변

3

가장 간단한 방법은 코드에서 패키지 레벨의 에러 값을하는 것입니다 당신이 더 많은 정보를 전달하려면

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 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 패키지 인 frm을 얻는 중 오류가 일치하는 오류 정의를 제공하지 않는다고 생각합니다. 하지만 오류 유형에 대해 먼저 전환 한 다음 나중에 오류 세부 정보로 전환 할 수 있다는 것이 맞습니다. 이 응용 프로그램으로 충분할 것입니다. 이제이 요청을 표준 HTML 패키지로 다시 공급하는 방법을 알아야합니다. 감사합니다. –

1

오류 인터페이스를 구현하고 처리하기 쉬운 오류를 직접 만들 수 있습니다.

런타임 오류의 경우 a.k.a 패닉. 당신은 패닉이라고 생각하는 함수에 recover()를 포함시킴으로써 복구 할 수 있습니다. 패닝 함수가 반환되기 전에 호출됩니다.

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

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

switch 다음이된다 :

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

아, 내가 공포가 내 코드가 처리 할 수없는 오류가 날 때 코드를 중지 할, 당신이 오해 생각 : 오류, 당신은 중첩 된 switch에서이 검사를 포함 할 수 있습니다. 그것은 내가해야하는 모든 문제를 포착하지 못한다고 말하는 디버그를 제공합니다. 감사합니다. –

+0

아마도 "오류 인터페이스 구현"은 사용자가 선택한 대답이기 때문에 이해하지 못했을 것입니다. – Sridhar