Когда ожидается, что метод net / http Serve вернет ошибку? - PullRequest
0 голосов
/ 18 апреля 2019

Учитывая следующую функцию:

func main() {
    l := createListener(8080)
    r := ksws.CreateRouter()

    if err := http.Serve(l, r); err != nil {
        fmt.Println("An error occured.")
    }
}

Мне интересно, почему я должен отлавливать ошибку, возвращаемую методом http.Serve?Кажется, что здесь никогда не возвращается ошибка.

Однако, согласно документации https://golang.org/pkg/net/http/#Serve, метод Serve всегда возвращает ненулевую ошибку.

Может кто-нибудь дать мне несколькоруководство по этому вопросу?

Ответы [ 3 ]

4 голосов
/ 18 апреля 2019

Простой случай: когда порт 8080 уже используется, у вас будет ошибка:

listen tcp :8080: bind: address already in use

Другой случай: http.Serve вызывает srv.trackListener, что также может привести к сбою в случае, если go не удалось добавить слушателя.

Также: http.Serve вызывает l.Accept(), что также может привести к сбою ...
Так что есть много возможных случаев ...

Кроме того, go идиоматично проверять все ошибки, возвращаемые любой функцией.

PS: Лучше иметь избыточную проверку ошибок, чем тихую не работающую программу (imho) ...

3 голосов
/ 18 апреля 2019

Посмотрите на исходный код, и он может пролить свет на ваш вопрос.

https://golang.org/src/net/http/server.go?s=75585:75634#L2838

// Serve always returns a non-nil error and closes l. // After Shutdown or Close, the returned error is ErrServerClosed.

Таким образом, ошибка всегда будет возвращаться либо с real error, если что-то пошло не так, либо с ErrServerClosed в случае отключения или закрытия, что происходит по нескольким причинам.

0 голосов
/ 18 апреля 2019

в вашем коде, когда вы нажимаете Ctrl-C, обратите внимание, что печать не происходит, потому что программа закончилась. вы должны слушать сигналы, чтобы предотвратить такое поведение.

package main

import (
    "fmt"
    "net/http"
    "os"
    "os/signal"
    "time"
)

func main() {

    c := make(chan os.Signal, 1)
    signal.Notify(c, os.Interrupt)

    r := http.NewServeMux()
    srv := &http.Server{
        Addr:    ":0",
        Handler: r,
    }

    go func() {
        if err := srv.ListenAndServe(); err != nil {
            fmt.Println("An error occured.")
        }
    }()
    // Block until a signal is received.
    <-c
    srv.Close()
    fmt.Println("rr")
    <-time.After(time.Second)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...