2015-08-02 11 views
5

Typ Go w wersji error jest dość szeroki, a rzeczywisty typ może się różnić w zależności od platformy i wersji. Czy filtrowanie błędów, których spodziewamy się za pomocą wartości łańcucha błędu, to idiomatyczne: error.Error()?Błędy filtrowania idiomatycznego w Go

Na przykład:

_, err := conn.Write(b) 
if err != nil { 
    if !strings.Contains(err.Error(), "peer reset") { 
     log.Print(err) 
    } 
    return 
} 

Czy istnieje lepszy sposób to zrobić?

+0

Wyczerpanie w łańcuchu reprezentującym "błąd" jest w najlepszym razie delikatne i nie jest dobrym pomysłem. Napisałem [odpowiedź] (http://stackoverflow.com/a/30178766/55504) na inne pytanie, które dotyczy sposobów, w jakie autor pakietu może popełniać błędy, które są testowalne przez konsumentów. Jeśli potrzebujesz przetestować lub obsłużyć błędy, które nie używają jednej z tych prostych metod, to znalazłeś lukę w tym pakiecie i zgłosisz to jako problem. Posunąłbym się tak daleko, by naprawić go widelcem, zanim zacznę grzebać z ciągiem błędów. –

+0

Twój nowy tag "SO" z ciągiem znaków nie ma dla mnie żadnego sensu; Polecam usunięcie go. –

Odpowiedz

1

Nie jestem pewien, czy mówię coś, czego nie wiesz, ale widziałem kilka sposobów, aby sobie z tym poradzić: porównaj ze znanymi przypadkami, kiedy są eksportowane i pojawiają się w godoc, jak io.EOF lub os.ErrNotExist ; używanie asercji lub przełączników typu, gdy dokumenty obiecują błąd określonego typu, na przykład *os.PathError lub *os.LinkError; lub rezygnując i patrząc na wiadomości. Pierwszy powinien być wystarczająco jasny, a Ty zrobiłeś trzecie pytanie; sprawdzanie typu może wyglądać następująco:

if pathErr, ok := err.(*os.PathError); ok { 
    log.Fatal("Bad path " + pathErr.Path + ", giving up") 
} else if err != nil { 
    return err 
} 

myślę, że to byłoby rzadkie, ale jeśli miał kilka możliwych rodzajów zaangażowany, można conceivably użyć type switch:

switch err.(type) { 
case *os.PathError, *os.LinkError: 
    log.Fatal("oof") 
case nil: 
    // nothing; prevents default 
default: 
    log.Fatal("huh") 
} 

(Wybór błędu i zachowanie tutaj jest trochę głupie - próbuję po prostu wstawić szablon ze składnią.)

Trudna część, o której wspominasz w swoim pytaniu: może nie być jasne, jakie masz gwarancje na temat błędów Być zwracane. Wiem, że na przykład, 1.5 release notes mówią, że są standaryzowane bardziej na net.OpError dla błędów sieci niż wcześniej, ale to wszystko, co wiem. Spelunking w źródle pakietu, do którego dzwonisz, lub zadawanie pytań ludziom, może być w porządku, jeśli są ważne sprawy, które uważasz za niejasne.

+1

Podsumowałeś, gdzie aktualnie jestem. –

+0

Twój przykład to błędy sieciowe; Zastanawiam się, czy warto pytać o orzechy golang o dodanie '(* net.OpError) .Type()' gdzie 'Type' jest jednym ze zbioru znanych wartości błędów (wyobrazić,' net.ErrConnReset', 'net.ErrAddrInUse' , itp.) - lub do standaryzacji 'opError.Error()' lub do udokumentowania, czy niektóre rzeczy są w rzeczywistości niezawodne, ale nie udokumentowane. – twotwotwo

+0

(Jeśli nie 'Type()', może 'Code()' lub 'Errno()' używając kodów błędów POSIX.) – twotwotwo