net / http Serve方法何时应返回错误?

Given the following function:

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

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

I'm wondering why I should catch the 'error' returned from the 'http.Serve' method? It seems that an error is never returned here.

However, according to the documentation https://golang.org/pkg/net/http/#Serve the Serve method always returns a non-nill error.

Can someone provide me some guidance on this?

Simple case: when port 8080 already used you'll have error:

listen tcp :8080: bind: address already in use

Another case: http.Serve calls srv.trackListener which also may fail in case go didn't manage to add listener.

Also: http.Serve calls l.Accept() which also may fail...
So there are many possible cases...

And also it's idiomatic for go to check all errors returned by any function.

PS: It's way better to have redundant error check than to have silent not working program (imho)...

Take a look at the source code and it might shine some light into your question.

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.

So the error will alway be return either with a real error if something went wrong or the ErrServerClosed in case of a shutdown or close, which happen for several reasons.

in your code when you ctrl-c, note that the prints does not occur because the program has ended. you should listen to signals to prevent that behavior.

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)
}